Índice:
- Etapa 1: O Sensor IMU
- Etapa 2: as coisas nem sempre são fáceis e limpas
- Etapa 3: teste inicial
- Etapa 4: solução de problemas
- Etapa 5: Lendo os dados do sensor
- Etapa 6: vamos aprofundar mais nas leituras / dados
- Etapa 7: Podemos afetar a temperatura e a aceleração
- Etapa 8: o acelerômetro e o giroscópio
- Etapa 9: (trabalho em andamento) o magnetômetro
Vídeo: Wallace - DIY Autonomous Robot - Part 5 - Add IMU: 9 Steps
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:38
Estamos prosseguindo junto com Wallace. O nome Wallace veio de uma mistura de "Wall-E" e de um projeto anterior (reconhecimento de voz) e, ao usar o utilitário "espeak", soou um pouco britânico. E como um criado ou mordomo. E esse é o objetivo final: que este projeto se transforme em algo útil. Portanto, "Wallace".
Wallace pode se mover, ele pode evitar obstáculos usando sensores de distância IR (recentemente, de alguma forma eles fritaram (?) (Tenho que olhar isso quando eu tiver uma chance), também tem alguns sensores de distância acústicos (três deles estragaram ao mesmo tempo, junto com um expansor MCP23017) e, finalmente, pode detectar mudanças na corrente do motor para saber quando bate em algo.
Além dos sensores, Wallace "se lembra" dos 100 movimentos e faz algumas análises rudimentares usando o histórico de movimentos.
O objetivo até agora para Wallace é apenas tentar seguir em frente e saber quando ele está preso em algum padrão repetitivo (como em um canto) e não realmente avançar.
Passei por várias iterações de movimento e navegação, e a dor de cabeça consistente tem sido durante a rotação.
Como Wallace é um robô rastreado e eu queria manter as coisas mais simples no software (para mais tarde), para girar eu apenas o faço girar / girar no lugar. Portanto, aplique potência / ciclo de trabalho igual, mas oposto, aos motores.
O problema encontrado é devido ao design da plataforma do robô Agente 390. As correias da esteira tendem a roçar nas laterais. E pior, um lado faz isso mais do que o outro.
No chão e na reta, não tem sido um problema. Ele aparece no carpete. Eu escolhi manter Wallace longe do carpete depois que seus rastros ficaram sujos (eles pegam a sujeira extremamente fácil).
O verdadeiro problema é quando girar no chão.
Se eu fizer com que o software aplique um ciclo de trabalho de alto nível, ele gira de forma mais ou menos consistente. No entanto, durante um ciclo de trabalho baixo, ele pode ou não girar. Ou pode girar um pouco e depois diminuir a velocidade. A ação de pivô parece incontrolável por meio do software ou, na melhor das hipóteses, muito difícil.
O problema aparece durante a navegação e movimentação ao redor ou para longe de obstáculos. Ele pode se desviar muito descontroladamente ou pode ficar preso ao tentar fazer mudanças muito pequenas, sem realmente se mover.
E assim a explicação acima motivou este Instructable.
Inicialmente, eu queria dispensar ou atrasar a introdução de uma unidade de detecção de movimento (IMU), porque eles são A) complicados, B) barulhentos, C) erros podem ser introduzidos com o tempo, etc, etc. Meu pensamento tinha é que poderíamos nos sair muito bem avançando para os sensores de laser infravermelho com tempo de voo. E poderíamos - usando lasers, poderíamos saber se o robô girou ou não, rastreando as mudanças na distância.
Na verdade, também poderíamos (mais ou menos) fazer isso agora, com os sensores acústicos.
No entanto, tudo isso é uma forma muito indireta e complicada de responder a uma pergunta simples: "fizemos rodízio ou não?"
Pareceu-me que usar os sensores a laser ToF me levaria ao próximo nível de software; a saber, SLAM (Simultaneous Localization and Mapping). Eu não estava pronto para ir para lá ainda.
É uma boa coisa fazer um projeto de robô em camadas, com as primeiras camadas (inferiores) sendo mais simples e as últimas (superiores) sendo mais abstratas e lidando com questões mais difíceis.
As camadas podem ser pensadas da seguinte forma:
- estrutura física do robô / base estrutural mecânica
- sistema de acionamento rudimentar (Raspberry, Roboclaw, motores, cabeamento, etc, software básico, acionado por teclado)
- circuitos essenciais para suportar sensores (deslocador de tensão bidirecional, expansor de porta, parada de emergência, distribuição de energia, etc)
- sensores para evitar obstáculos (acústicos, IR)
- essencial, posicionamento básico e detecção de movimento (acelerômetro, giroscópio, magnetômetro, codificadores de motor, codificadores de roda)
Você pode criar sua própria lista. Os pontos sobre esta lista são que você provavelmente deve fazer isso mais ou menos nessa ordem, e também que se você gastar algum tempo em cada camada para obter um bom estado de funcionamento, isso deve ajudá-lo mais tarde, conforme as coisas ficam mais complicadas.
A lista acima pode ser mais ou menos mapeada para essas camadas conceituais no software.
- SLAM (localização e mapeamento simultâneos)
- Controle e consciência de movimento, rotação
- Evitar Obstáculos Básicos
- Controle e detecção de dados do sensor
- Movimento essencial para frente, para trás, esquerda e direita, acelerar, desacelerar, parar
Como você pode ver, para esta lista, os primeiros itens seriam as camadas superiores, mais complicadas que abordam questões e questões mais abstratas, como "onde estou" e "para onde estou indo", enquanto os últimos itens seriam os camadas de software inferiores que tratam de "como falar / ouvir o sensor A" ou "como mover esta roda".
Agora, não estou dizendo que quando você começa em uma camada, você a terá concluído e então estará na próxima camada, para nunca mais retornar à anterior. Um projeto de robô pode ser muito parecido com métodos modernos de desenvolvimento de software iterativo (ágil, SCRUM, etc).
Só estou dizendo para dedicar um tempo a cada um. Você terá que equilibrar o quanto fazer em cada um e decidir se o que está tentando fazer em uma determinada camada vale o tempo e o trabalho.
Existe um certo "conflito" ou "tensão" entre duas idéias ou direções concorrentes.
Um é o que eu chamaria de "plug-n-play" para resolver o problema A.
O outro é DIY (faça você mesmo). E esse pode nem ser o melhor rótulo para essa outra ideia.
Aqui está um exemplo de cada um, espero que você veja a tensão ou conflito entre as duas opções.
Para este exemplo, vamos agrupar SLAM, evasão de obstáculos e movimento básico essencial como um problema a ser resolvido ao mesmo tempo.
- Se decidirmos seguir a rota plug-n-play, saltamos imediatamente (dependendo do orçamento) para coisas como lasers rotativos montados no topo, ou câmera de profundidade de campo, ou lasers ToF, e a IMU (tópico deste Instrutível).
- Se nós, por outro lado, quisermos seguir o segundo caminho, podemos tentar extrair cada bit de informação possível de alguns sensores acústicos ou sensores IR, ou nenhum sensor - nós apenas usamos o monitoramento da corrente do motor (bump)
O que pode ser dito sobre o nº 1 e o nº 2? Uma coisa seria que teríamos aprendido muito mais fazendo o # 2. As limitações de ter apenas sensores acústicos para trabalhar nos obriga a pensar em muito mais questões.
Por outro lado, se estivermos muito focados em fazer as coisas via # 2, podemos estar perdendo tempo, porque estamos pedindo mais do que deveríamos dos sensores acústicos.
Mais um conceito ou ideia para se pensar: Qual mistura de hardware e software melhor responde às questões de "como fazer" e que mistura de software (e hardware?) Responde à questão de "o que", "quando", "onde". Porque "como fazer" é tipicamente uma questão de nível inferior da qual "o quê", "quando" e "onde" dependem para obter uma resposta.
De qualquer forma, tudo o que foi dito acima foi apenas algo para se pensar.
No meu caso, depois de muito esforço e tendo o problema consistente e irritante de atrito na esteira e incapaz de obter controle e movimento consistentes, é hora de fazer outra coisa.
Assim, este Instructable - um IMU.
O objetivo é que se a IMU disser que o robô NÃO está girando, aumentemos o ciclo de trabalho. Se girarmos muito rápido, diminuímos o ciclo de trabalho.
Etapa 1: O Sensor IMU
E assim, nosso próximo sensor a adicionar a Wallace é o IMU. Depois de alguma pesquisa, decidi usar um MPU6050. Mas então, neste momento, o MPU9050 (e ainda mais recentemente, o MPU9250) parecia uma ideia ainda melhor.
Minha fonte preferida é a Amazon (nos EUA). Então, encomendei dois deles.
O que consegui de fato (parece não haver controle sobre isso; é isso que não gosto na Amazon) foram dois MPU92 / 65. Eu me pergunto um pouco sobre a designação. Dê uma olhada nas imagens; isso parece ser uma designação de "família". Em qualquer caso, é nisso que estou preso.
Adicioná-lo é muito simples - pegue uma placa proto com trilhas de conexão, solde o sensor na placa, adicione um bloco de terminais de parafuso de 10 pinos (eu comprei o meu na Pololu).
Para minimizar qualquer interferência, tentei colocar esses sensores longe de todo o resto.
Isso também significava usar alguns parafusos / porcas de náilon.
Vou usar o protocolo I2C. Esperançosamente, o comprimento total do fio não será tão ruim.
Há muitas informações em outros lugares sobre as conexões básicas e os níveis de voltagem, etc., então não vou repetir isso aqui.
Etapa 2: as coisas nem sempre são fáceis e limpas
No momento em que este livro foi escrito, não parecia haver muito conteúdo online para este MPU-92/65 em particular. O que está disponível, assim como a maioria dos sensores, parecem ser exemplos usando o Arduino.
Tento tornar esses Instructables um pouco diferentes, apresentando um processo não tão limpo, porque as coisas nem sempre funcionam imediatamente.
Suponho que esses Instructables sejam mais semelhantes a um blog do que A-B-C direto, 1-2-3 "é assim que você faz".
Etapa 3: teste inicial
Pelas imagens da etapa anterior, os fios vermelho e preto que vão para os sensores são, obviamente, VCC (5V) e GND. Os fios verde e amarelo são as conexões I2C.
Se você já fez outros projetos I2C, ou está acompanhando essas séries, então já conhece o "i2cdetect", e esse é o primeiro passo para saber se o Raspberry pode ver o novo sensor.
Como você pode ver nas imagens desta etapa, nossa primeira tentativa não foi bem-sucedida. A IMU não aparece (deve ser a identificação do dispositivo 0x68).
No entanto, a boa notícia é que o barramento I2C está operando. Vemos um dispositivo 0x20 e é o expansor de porta MCP23017 (atualmente responsável pelos sensores acústicos HCSR04).
Não é fácil ver na imagem, mas eu conectei os fios verdes e amarelos da mesma cor da IMU ao MCP23017 (veja abaixo à esquerda na imagem)
Teremos que resolver alguns problemas.
Etapa 4: solução de problemas
Usando a configuração de continuidade em um voltímetro (aquele com tom agudo), testei as conexões VCC (5V), GND, SDA e SCL. Esses eram bons.
A próxima tentativa foi desconectar o MCP23017 do barramento I2C, deixando apenas o MPU-92/65 no barramento. Isso provou ser infrutífero - "i2cdetect", em seguida, não mostrou nenhum dispositivo.
Então, em seguida, desmontei o sensor do totem e o reconectei diretamente ao barramento bidirecional de 5 V a 3 V; ou seja, direto para a framboesa. (fios mais curtos?).
E voila. Desta vez, houve sucesso. Vemos 0x68 aparecer usando "i2cdetect".
Mas ainda não sabemos por que funcionou desta vez. Poderia ser o comprimento dos fios? O local anterior?
Nota: Não fazia diferença se o ADO estava aterrado ou não. Pode ser que haja resistores pullup e pull-down integrados. O mesmo pode ser verdade para FSYNC.
Em seguida, reconectei o MCP23017. Portanto, agora temos dois dispositivos no barramento I2C. (veja a imagem). Sucesso, agora vemos 0x20 e 0x68 com i2cdetect.
Os vídeos mostram um pouco mais sobre o que aconteceu durante a solução de problemas.
Etapa 5: Lendo os dados do sensor
Várias abordagens
Decidi fazer várias abordagens para obter informações úteis do sensor. Aqui estão eles, não em qualquer ordem:
- tente alguma programação básica
- dê uma olhada em alguma documentação online sobre registros
- dê uma olhada nos exemplos e / ou códigos de outras pessoas
Por que essas abordagens? Por que não apenas procurar alguma biblioteca ou código existente?
Experimentando e tentando algumas ideias, podemos absorver melhor algum conhecimento não apenas sobre esse sensor específico, mas também ganhar alguma técnica, habilidade e maneiras de pensar sobre como lidar com algo novo, e algo que pode não ter muita documentação; algo que pode ter muitas incógnitas.
Além disso, uma vez que tenhamos testado e testado algumas de nossas próprias ideias e obtido algum insight, estaremos em uma posição melhor para avaliar o código ou a biblioteca de outra pessoa.
Por exemplo, depois de olhar algum código C ++ para o MPU9250 no github, percebi que ele estava me forçando a usar interrupções, o que ainda não desejo fazer.
Além disso, ele vem com coisas extras como calibração; novamente, algo em que ainda não estou interessado.
Pode ser que o que eu preciso fazer para responder à simples pergunta "o robô está girando sim ou não" possa ser respondido de forma muito simples, apenas lendo alguns registros.
Registros
No momento em que este texto foi escrito, não parecia haver muito disponível neste sensor. Na verdade, se você der uma olhada nas imagens que vêm com este Instructable e dar uma olhada nas inscrições nos chips reais, me pergunto se isso não é uma cópia. Não estou relacionando o que vejo com nada do Invense. Apesar disso, optei por olhar as informações de registro dos modelos que encontrei: o MPU-6050 e o MPU-9250.
Em ambos os casos, o seguinte é o mesmo para ambos. E para começar, presumimos que também será o mesmo para este MPU-92/65.
59 a 64 - medições do acelerômetro
65, 66 - medições de temperatura 67 a 72 - medições do giroscópio 73 a 96 - dados do sensor externo
Um item a ser observado: o MPU-6050 parece NÃO ter um magnetômetro, enquanto o MPU-9250 (e presumimos que este também) tem um.
Algumas informações mais interessantes, esperançosamente úteis, coletadas do documento de registro:
Informações do magnetômetro:
ID do magnetômetro: 0x48 registra 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 HX3 HX2 HX1 04 HX1 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 HZ4 HZ7 HZ1HZ1 HZ13 HZ1 HZ13 HZ1 HZ1 HZ1 HZ1 HZ7 HZ1 HZ1 HZ1 HZ1 HZ7 HZ1 08 HZ11 HZ8 HZ7 HZ1 08 13 HZ8 HZ1 08 13 HZ11 HZ1 08 13 HZ1 08 HZ11 HZ6 13 HZ1 08 HZ1 HZ1 08 HZ7 HZ1 231 HZ1 09 HZ3 HZ1 087 HZ6 13 HZ6 13 HZ6 13 HZ1 HZ1 HZ1 HZ1 HZ1 07 HZ6 13 HZ6 13 HZ3 HZ1 HZ1 HZ1 HZ1 07 HZ3 HZ6 231 HZ1 09 HZ6? ST2 0 0 0 BITM HOFL 0 0 0 um detalhamento do que cada registro significa: HXL [7: 0]: Dados de medição do eixo X inferiores 8bit HXH [15: 8]: Dados de medição do eixo X superiores 8bit HYL [7: 0]: Dados de medição do eixo Y inferior 8bit HYH [15: 8]: Dados de medição do eixo Y superior 8bit HZL [7: 0]: Dados de medição do eixo Z inferior 8bit HZH [15: 8]: Dados de medição do eixo Z superior 8 bits
Programação
Outra informação dos documentos de registro é que parecia haver apenas cerca de 100 registros. Portanto, uma tática poderia ser escrever um programa simples que acessa o dispositivo (0x68) e tenta ler uma série de registros sequencialmente, sem qualquer consideração ao seu significado, apenas para ver quais dados podem ser vistos.
Em seguida, faça passagens sucessivas, usando o mesmo código, e compare os dados de uma passagem com os da próxima.
A ideia é que provavelmente poderíamos eliminar quaisquer registros que pareçam não ter dados (zeros ou FF?) Ou que absolutamente nunca mudem, e também poderíamos nos concentrar naqueles que mudam.
Então, aquele que estamos olhando apenas para aqueles que mudam, adicione uma função de média que calcule a média das últimas N leituras desse registro, para ver se há de fato um certo valor estável para aquele registro. Isso pressupõe que estamos mantendo o sensor bem imóvel e no mesmo local.
Finalmente, poderíamos então tentar coisas suavemente com o sensor, como empurrá-lo (acelerômetro, giroscópio) ou soprar nele (temperatura) ou girá-lo (os dois anteriores mais o magnetômetro) e ver o efeito que isso tem sobre os valores.
Gosto de usar a biblioteca wiringPi tanto quanto possível. Possui suporte para I2C.
Primeira corrida:
/********************************************************************************
* para construir: gcc first.test.mpu9265.c -o first.test.mpu9265 -lwiringPi * * para executar: sudo./first.test.mpu9265 * * este programa apenas produz uma série de (possíveis) registros do MCP23017, * e então do MPU9265 (ou qualquer outro MPU naquele endereço 0x68) * * Usei para validar se eu poderia até ler do sensor, uma vez que já * tinha confiança no MCP23017. * ************************************************** ***************************** / #include #include #include #include #include int main (int argc, char ** argv) {puts ("Vamos ver o que MCP23017 @ 0x20 tem a dizer:"); errno = 0; int deviceId1 = 0x20; int fd1 = wiringPiI2CSetup (deviceId1); if (-1 == fd1) {fprintf (stderr, "Não é possível abrir o dispositivo wiringPi I2C:% s / n", strerror (errno)); return 1; } para (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d", wiringPiI2CReadReg8 (fd1, reg)); fflush (stderr); atraso (10); } puts (""); puts ("Vamos ver o que MPU9265 @ 0x20 tem a dizer:"); errno = 0; int deviceId2 = 0x68; int fd2 = wiringPiI2CSetup (deviceId2); if (-1 == fd2) {fprintf (stderr, "Não é possível abrir o dispositivo wiringPi I2C:% s / n", strerror (errno)); return 1; } para (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d", wiringPiI2CReadReg8 (fd2, reg)); fflush (stderr); atraso (10); } puts (""); return 0; }
A segunda execução:
/********************************************************************************
* para construir: gcc second.test.mpu9265.c -o second.test.mpu9265 -lwiringPi * * para executar: sudo./second.test.mpu9265 * * Este programa mostra o número do registro junto com o valor lido. * * Isso torna útil canalizar (redirecionar) a saída para um arquivo e, em seguida, * várias execuções podem ser feitas para comparar. Pode dar algumas dicas sobre * quais registros são importantes e como os dados podem se comportar. * ************************************************** ***************************** / #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; } else if (! strncmp (argv [1], "0x68", strlen ("0x68"))) {deviceId = 0x68; } else if (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } puts ("Vamos ver o que MPU9265 @ 0x20 tem a dizer:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Não é possível abrir o dispositivo wiringPi I2C:% s / n", strerror (errno)); return 1; } para (int reg = 0; reg <300; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); atraso (10); } return 0; }
A terceira execução:
/********************************************************************************
* para construir: gcc third.test.mpu9265.c -o third.test.mpu9265 -lwiringPi * * para executar: sudo./third.test.mpu9265 * * Este programa é o resultado do segundo. Ele só lê a partir dos * registradores que indicaram uma diferença entre uma execução e a próxima.* ************************************************** ***************************** / #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; } else if (! strncmp (argv [1], "0x69", strlen ("0x69"))) {deviceId = 0x69; } puts ("Vamos ver o que MPU9265 @ 0x20 tem a dizer:"); errno = 0; int fd = wiringPiI2CSetup (deviceId); if (-1 == fd) {fprintf (stderr, "Não é possível abrir o dispositivo wiringPi I2C:% s / n", strerror (errno)); return 1; } para (int reg = 61; reg <= 73; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); atraso (10); } para (int reg = 111; reg <= 112; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); atraso (10); } para (int reg = 189; reg <= 201; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); atraso (10); } para (int reg = 239; reg <= 240; reg ++) {fprintf (stderr, "% d:% d / n", reg, wiringPiI2CReadReg8 (fd, reg)); fflush (stderr); atraso (10); } return 0; }
Então, o que aprendemos até agora? A imagem da tabela com áreas coloridas destacadas indica que a saída parece corresponder aos primeiros conjuntos de registros.
Os resultados até agora podem gerar novas questões.
Pergunta: por que existe apenas um resultado de registro para o grupo "externo"?
Pergunta: o que são todos esses registros desconhecidos "??????"
Pergunta: como o programa não é controlado por interrupções, ele solicitou dados muito devagar? muito rápido?
Pergunta: podemos afetar os resultados experimentando coisas com o próprio sensor enquanto ele funciona?
Etapa 6: vamos aprofundar mais nas leituras / dados
Acho que a próxima etapa antes de qualquer outra coisa é aprimorar o programa para:
- seja flexível em quanto atraso de loop (ms)
- seja flexível em relação a quantas leituras para dar uma média de execução por registro
(Tive de anexar o programa como um arquivo. Parecia haver um problema ao inseri-lo aqui. "Four.test.mpu9265.c")
Aqui está uma corrida usando as últimas 10 leituras para uma média, em um loop 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
A primeira coluna mais à esquerda é o número do registro. Em seguida, vêm as últimas 10 leituras desse registro. Finalmente, a última coluna é a média de cada linha.
Parece que os registradores 61, 69, 71, 189, 197 e 199 são apenas binários, ou estão prontos / não estão prontos, ou são o byte alto de um valor de 16 bits (negativo?).
Outras observações interessantes:
- registra 65, 193 - muito estável e mesmo valor
- registro 63, 191 - muito estável e mesmo valor
- registra 73, 112, 195, 201, 240 - todos em zero
Vamos relacionar essas observações de volta à imagem colorida e destacada da mesa anterior.
Registro 65 - temperatura
Registro 193 - ??????
Registro 63 - acelerômetro
Registro 191 - ??????
Registro 73 - externo
Cadastre-se 112 e em diante - ??????
Bem, ainda temos incógnitas, no entanto, aprendemos algo útil.
O registro 65 (temperatura) e o registro 63 (acelerômetro) estavam ambos muito estáveis. Isso é algo que esperávamos. Não toquei no sensor; ele não está se movendo, a não ser por quaisquer vibrações incidentais, pois o robô está apoiado na mesma mesa que meu computador.
Há um teste interessante que podemos fazer para cada um desses registros de temperatura / acelerômetro. Para esse teste, precisamos de outra versão do programa.
Etapa 7: Podemos afetar a temperatura e a aceleração
Nas etapas anteriores, reduzimos pelo menos um registro de temperatura e um de aceleração.
Com esta próxima versão do programa ("quinta.test.mpu9265.c"), podemos realmente ver uma mudança ocorrendo em ambos os registradores. Por favor, assista aos vídeos.
Mais escavações
Se voltarmos e olharmos as informações de registro, veremos que existem:
- três saídas de 16 bits para giroscópio
- três saídas de 16 bits para acelerômetro
- três saídas de 16 bits para magnetômetro
- uma saída de 16 bits para temperatura
No entanto, os resultados obtidos por nossos programas de teste simples foram todos saídas de 8 bits. (registros únicos).
Então, vamos tentar mais da mesma abordagem, mas desta vez lendo 16 bits em vez de 8.
Provavelmente teremos que fazer algo como a seguir. Vamos usar a temperatura como exemplo, já que é apenas uma saída de 16 bits.
// obter o descritor de arquivo fd…
int tempRegHi = 65; int tempRegLo = 66; int hiByte = wiringPiI2CReadReg8 (fd, tempRegHi); int loByte = wiringPiI2CReadReg8 (fd, tempRegLo); resultado int = hiByte << 8; // coloca os 8 bits de alta ordem na parte superior de um valor de 16 bits result | = loByte; // agora adicione na ordem inferior 8 bits, produzindo um número completo de 16 bits // imprima esse número ou use a função de gráfico horizontal de exibição anterior
De nossas etapas anteriores, vimos que o registro 65 é bastante estável, enquanto o registro 66 é muito barulhento. Como 65 é o byte de ordem superior e 66 o byte de ordem inferior, isso faz sentido.
Para leitura, podemos pegar os dados do registrador 65 como estão, mas podemos obter a média dos valores do registrador 66.
Ou podemos apenas calcular a média de todo o resultado.
Dê uma olhada no último vídeo desta parte; ele demonstra a leitura de todo o valor de temperatura de 16 bits. O código é "sixth.test.mpu9265.c"
Etapa 8: o acelerômetro e o giroscópio
Os vídeos desta seção mostram a saída do acelerômetro e do giroscópio, usando um programa de teste "seventh.test.mpu9265.c". Esse código pode ler 1, 2 ou 3 pares de bytes consecutivos (bytes hi e lo) e converte os valores em um único valor de 16 bits. Assim, podemos ler qualquer eixo único, ou podemos ler dois deles juntos (e soma as mudanças), ou podemos ler todos os três (e soma as mudanças).
Para reiterar, para esta fase, para este Instructable, estou apenas procurando responder a uma pergunta simples: "o robô girou / girou?". Não estou procurando nenhum valor preciso, como girar 90 graus. Isso virá mais tarde, quando começarmos a fazer SLAM, mas não é necessário para evitar obstáculos simples e movimentos aleatórios.
Etapa 9: (trabalho em andamento) o magnetômetro
ao usar a ferramenta i2cdetect, o MPU9265 aparece como 0x68 na tabela:
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: -- -- -- -- -- -- -- --
Há etapas extras necessárias para ler a parte do magnetômetro da IMU.
Do Invesense registra o documento em PDF:
REGISTROS 37 A 39 - I2C ESCRAVO 0 CONTROLE
- REGISTRO 37 - I2C_SLV0_ADDR
- REGISTRO 38 - I2C_SLV0_REG
- REGISTRO 39 - I2C_SLV0_CTRL
Recomendado:
Wallace, a criatura alienígena animatrônica: 9 etapas (com imagens)
Wallace, a Criatura Alienígena Animatrônica: Bem-vindo! Hoje vou mostrar como construir Wallace, uma criatura alienígena animatrônica. Para começar, você vai precisar de: x 1 cachorro Fur Real Friends (como este: https://www.ebay.com/p/1903566719)x 5 MG996R Servos x 1 Pololu Maestro 6 canais Servo controle
MPU6050 IMU + Arduino GYRO Bot simples: 4 etapas
Simples MPU6050 IMU + Arduino GYRO Bot: Usar um Gyro para controlar meus projetos era uma grande coisa na minha lista de desejos, mas além de adquirir o IMU, o resto foi difícil como pregos. A falta de conteúdo eficaz para extrair valores de pitch and roll de guinada me incomodou por mais de um mês. Depois de vários websi
Bluetooth e IMU com a placa Tactigon - Processamento: 7 etapas
Bluetooth e IMU com a placa Tactigon - Processando: Esta série de artigos explicará como usar os sensores integrados e as interfaces de comunicação do Tactigon para criar um controlador de gestos simples. Código fonte disponível aqui no GitHubNeste artigo, vamos aprender como usar simp
Robô autônomo Wallace - Parte 4 - Adicionar Sensores de Distância IR e "Amp": 6 etapas
Robô Autônomo Wallace - Parte 4 - Adicionar Sensores de Distância IV e "Amp": Olá, hoje começamos a próxima fase de aprimoramento dos recursos de Wallace. Especificamente, estamos tentando melhorar sua capacidade de detectar e evitar obstáculos usando sensores infravermelhos de distância e também aproveitar as vantagens do controlador de motor Roboclaw
Simulador de jogo do smartphone - jogue jogos do Windows usando o controle de gestos IMU, acelerômetro, giroscópio, magnetômetro: 5 etapas
SmartPhone Game Simulator- Jogue jogos do Windows usando Gesture Control IMU, acelerômetro, giroscópio, magnetômetro: Apoie este projeto: https://www.paypal.me/vslcreations doando para códigos de código aberto & suporte para maior desenvolvimento