|
|
|
2019
|
|||||||||
|
Autores: |
|||||||||||
|
|
Marcelo Lopes (Nº 1170959) |
1170959@isep.ipp.pt |
|||||||||
|
|
António Leite (Nº 1170760) |
1170760@isep.ipp.pt
|
|||||||||
|
|
|||||||||||
|
|
|||||||||||
|
O trabalho realizado teve como objetivo principal o desenvolvimento de um robô que se autoequilibra. Este trabalho ficou subdividido em vários projetos pequenos de complexidades variadas que foram, posteriormente, montadas em conjunto de forma a conseguir o resultado pretendido. Existem na atualidade diversos projetos envolvendo este tipo de tecnologia tais como a Segway ou a Hoverboard.
Podem-se encontrar também projetos DIY (Do It Yourself) destinados aos estudantes em que se usam placas Arduino , motores e baterias [3]. No entanto, cada projeto tem um objetivo diferente, alguns são seguidores de linha [4], outros são controlados por uma App, mas em termos de hardware a maior diferença é sem dúvida no microcontrolador a utilizar [5]. Neste projeto o microcontrolador é um Atmel AVR. Procurou-se com este projeto aplicar os conhecimentos adquiridos ao longo do curso, bem como, autonomamente, realizar um trabalho de pesquisa acerca do mesmo.
|
|||||||||||
|
Regulador de tensão transforma os 12V fornecidos pela fonte em 5V, tensão utilizada por quase todos os componentes, sendo a exceção os motores que são controlados pela ponte H com os 12V. O microcontrolador comunica por I2C com o acelerómetro e giroscópio obtendo os seus respetivos valores, após o processamento são atualizados os motores pela ponte H e apresentado no display os valores tratados respetivos à inclinação e temperatura.
|
|||||||||||
|
Foi utilizado um regulador de tensão inserido no circuito estudado nas aulas teóricas com o intuito de conseguir transformar a tensão de entrada, que geralmente é superior à necessária, numa tensão apropriada para o microcontrolador, neste caso 12V transformados em 5V. Conseguindo, assim, a tensão de 5V para o controlo e a tensão superior para os motores. Datasheet
Este componente teve por objetivo o de controlar os motores para que estes funcionassem da maneira correta de acordo com as instruções fornecidas, através da limitação da corrente de saída do microcontrolador. Sem este componente os motores não iriam funcionar e poderiam, até, danificar o microcontrolador devido às altas correntes. Datasheet
Utilizou-se motores DC para o movimento do robô, tendo o objetivo do projeto o equilíbrio, a variação da velocidade dos motores DC é uma abordagem possível e funcional. Neste caso foram necessários dois motores, sendo possível que os motores andem em direções opostas e com velocidades diferentes. Para este trabalho foram utilizados motores 12V.
![]() O módulo MPU-6050, tem um sensor Acelerómetro de 3 eixos, sensor Giroscópio de 3 eixos e sensor de temperatura, a comunicação com o mesmo foi efetuada por I2C. O MPU 6050 tem 96 registos mapeados desde o endereço 0x0D até 0x75, foi consultada a respetiva datasheet (referente aos registos) de forma a percebermos os endereços onde são guardados os dados do acelerómetro, giroscópio e temperatura. Datasheet
Utilizou-se um display 16x2 com a comunicação a 4bits. Colocar display em funcionamento foi prioridade com o intuito de visualizar dados no ecrã e ser possível comprovar o bom funcionamento dos módulos seguintes.
Este é um microchip de alto rendimento, possuí 8KB ISP flash memory com a capacidade de leitura enquanto se escreve no mesmo, 512B EEPROM, 1KB SRAM, 23 pinos I/O divididos em 3 portos (B,C,D), 32 registos, 3 timers flexíveis com comparadores, interrupções externas e internas, USART, comunicação 2-wire serial interface orientada ao Bit, SPI serial port, 6 canais de conversão A/D 10-Bit. Tensão de operação entre 2,7 V e 5,5 V. Sabendo o projeto a implementar, foi escolhido este AVR pelo facto de ser suficiente e o mais apropriado às necessidades do trabalho.O atmega88 utilizado encontra-se configurado com uma frequência de clock de 8MHz. Esquema elétrico
PCB
A placa de PCB foi desenhada com vista à fácil adaptação e ligação dos componentes. Foi inserido um socket para a aplicação do módulo MPU-6050, um socket para o simples encaixe do microcontrolador. O conector J1 é para a entrada da alimentação e ainda mais dois J2 e J3 para serem ligados os motores. Vista 3D
|
|||||||||||
|
Fluxogramas
Descrição das funçõesFunção Init()Aqui são inicializados os ports do microcontrolador que serão utlizados. Neste caso utilizou-se apenas o PORTB, sendo o pino 0 para piscar um LED à frequência de 1Hz, o pino 1 para gerar a onda PWM de controlo dos motores e o pino 6 e 7 para a seleção da direção dos mesmos. Estes pinos foram definidos como saídas. Foram utilizados 3 timers, o timer 0 para a marcação de um tempo de 500ms, o timer 2 para a contagem de um tempo com uma grande precisão, na ordem dos 208us, e o timer 1 para gerar uma onda PWM à frequência de 50Hz. De forma a ocorrerem interrupções nos timers utilizados para a contagem de tempos (timer 0 e 2), é necessário ativar as interrupções colocando a 1 o bit I do SREG, ou utilizando a função sei() da linguagem C. Toda esta informação foi consultada pela datasheet do atmega e referente pinout. Função get_mpu_values() Leitura dos valores do acelerómetro, giroscópio e de temperatura fornecidos pelo módulo mpu-6050, para tal é chamada a função twi_read passando por referência a respetiva informação a ler. Nesta função é realizada a correção dos valores do acelerómetro após se ter verificado algum offset em cada um dos eixos e ainda a conversão do valor para aceleração gravitacional equivalente em g. O acelerómetro foi utilizado com a precisão de 16384 LSB/g e o giroscópio 131 LSB/°/s, fazendo a divisão dos valores lidos do acelerómetro e do giroscópio por 16384 e 131 respetivamente, obtêm-se o valor em g’s e em °/s. Cálculo inclinação Após se obterem os valores do módulo, estes são tratados baseado no seu funcionamento. Focamo-nos na inclinação sobre o eixo X, pois é a orientação para a qual o robô tenderá a cair. Ao ângulo detetado chamou-se theta, e para o determinar utiliza-se como referência a aceleração gravitacional sobre o eixo Z, sendo esta conhecida, 1 g. Foi deduzida a seguinte igualdade para determinar o ângulo theta:
Assim sendo, theta é dado pela tangente inversa da aceleração em X sobre a aceleração em Z. O valor do giroscópio após ser atualizado pela função get_mpu_values(), encontra-se em graus por segundo, desta forma, ao se multiplicar ao valor lido o tempo decorrido em segundos desde a última leitura, descobrimos a variação em graus. Filtro complementar Estudando o módulo mpu-6050, descobre-se que o acelerómetro tem muito ruído a curto prazo, mas a longo prazo retorna medições mais precisas, o contrário se verifica no giroscópio, a curto prazo as variações são confiáveis, mas a longo não. Assim sendo e de forma a se obter o melhor dos dois mundos, aplicamos um filtro passa baixo nos valores do acelerómetro, confiando 95% no valor anterior e apenas 5% no valor lido. De seguida fundiu-se a informação do giroscópio confiando 99% nesta e apenas 1% na do acelerómetro. Desta forma, a curto prazo foi eliminado o ruído do acelerómetro confiando-se nas rápidas variações detetadas pelo giroscópio e a longo prazo mantemos os valores do acelerómetro. Função erro() Esta função tem por objetivo escrever no Display a palavra “erro” e consequentemente parar o programa. Esta função foi colocada dentro das funções mpu_init() e twi_read() com o intuito de sempre que houver um erro na comunicação de dados ser possível visualizar que tal aconteceu. Da mesma maneira, caso o programa não funcione da maneira esperada mas a função erro não aparecer, é possível deduzir que o erro será de outro tipo que não o descrito. Função controlador_PID() Esta função, tal como a implementação do filtro complementar, tem por objetivo a de minimizar o erro no tratamento de dados do acelerómetro. Para tal, foram caracterizados o ganho proporcional (Kp) e o derivativo (Kd), sendo o Kp direcionado à estabilidade do robô dado o ângulo instantâneo (Kp*theta) e o Kd direcionado á variação de ângulos ocorrida num certo intervalo de tempo (Kd*(theta-last_theta)). O ganho integral não entrou no cálculo, foi deduzido que a sua constante seria 0, pois o robot não apresenta erro acumulativo ao longo do tempo. Isto deve-se à fusão dos dados do acelerómetro e giroscópio que foram dimensionados para a correção deste efeito. Função mpu_init() Esta função trata de inicializar o acelerómetro, a cada instrução é identificado o acknowledgment retornado pelo módulo e em caso de não ser o esperado chama a função erro(). Aqui estabelece-se o bit rate da comunicação para 100 kHz e a referência de clock do módulo. Segundo o register map do MPU-6050 (pág.40) é recomendado o uso de um eixo do giroscópio como referência para aumento da estabilidade, assim sendo, foi selecionada a opção “PLL with X axis gyroscope reference”. Função twi_read() Aqui são pedidos os dados ao dispositivo em questão, sendo que é passado como parâmetro o registo a ser lido e retornado valor. Mais uma vez a cada instrução identifica -se o acknowledgment retornado pelo módulo e em caso de não ser o esperado chama a função erro(). Função main() É na função main que se fazem as declarações de variáveis a utilizar no tratamento dos dados do acelerómetro, bem como dos valores de ângulos calculados e do valor PID. São também chamadas as funções de inicialização dos ports, do acelerómetro e do LCD. Dentro do ciclo while é, então, chamada a função get_mpu_values(), feito o cálculo da inclinação, aplicado o filtro complementar, atualizados os motores e de 200 em 200ms atualizado o display. Já com o theta e o PID_value calculados passa-se para a condição que irá determinar caso os motores andem no sentido positivo ou negativo dependendo do sinal do ângulo determinado (caso theta = 0 os motores não estão ativos). Theta tem limite de 60º visto que foi determinado que caso o robô se incline mais de 60º já não há hipótese de este conseguir reverter a inércia e voltar á posição de equilíbrio. Tendo o sentido estabelecido é feito o cálculo da velocidade de rotação dos motores e atribuido o resultado ao OCR1A. Esta operação, já descrita anteriormente, utiliza o valor do PID_value e soma a uma constante sendo o resultado no máximo 155. Função referentes ao LCD O LCD foi colocado em funcionamento com recurso à datasheet para perceber o funcionamento mais detalhado do mesmo e de seguida com uma biblioteca lcd.h. Foi necessário adaptar a biblioteca ao nosso código tendo discriminado a frequência de oscilação do nosso microcontrolador e os ports onde se encontravam ligados os pinos de dados e controlo do display. Com a biblioteca o autor disponibilizou um conjunto de funções que são utilizadas ao longo do nosso código e se encontram no ficheiro lcd.c [12]. lcd_clrscr(); -> ao chamar esta função, que pode ser interpretada como “lcd clear screen”, ela faz isto mesmo, limpa o display ficando pronto a nova impressão. lcd_gotoxy(0,0); -> esta função interpreta-se como, “lcd go to x y”. Seleciona-se a posição do lcd onde pretendemos iniciar a escrita, como estamos perante um lcd 16x2, podemos escolher valores entre 0 e 15 como primeiro parâmetro e 0 ou 1 como segundo. lcd_puts(string); -> esta função imprime no ecrã a string passada como parâmetro. Como apenas se recorre a strings para efetuar a impressão, os valores inteiros que queiramos imprimir têm de ser convertidos com recurso à função itoa(). Os valores referentes ao ângulo de inclinação utilizados ao longo do código são do tipo float, mas são impressos no LCD como inteiros. Para transformar um valor float em string teríamos de recorrer à função: sprintf(string,"%.3f", theta), e para o bom funcionamento da mesma é necessário realizar uma alteração no compilador, ativando “vprintf library”. Esta simples alteração tem um impacto gigante na memória de programa utilizada, assim sendo, decidiu-se usar apenas a função itoa() para não sobrecarregar o microcontrolador.Nas figuras seguintes é possível identificar as diferenças e a alteração a ser efetuada.
|
|||||||||||
|
video demonstração |
|||||||||||
|
Em suma, pode-se afirmar que o projeto global foi um sucesso na medida em que se atingiu o objetivo proposto inicialmente do autoequilíbrio do robô. O protótipo atual consegue equilibrar-se, sem qualquer ação externa ou até suportar ligeiros toques, indefinidamente. No entanto, carece da robustez para se equilibrar caso a força externa seja moderada. |
|||||||||||
|
[1] Segway Inc.'s Human Transporter (HT) models, acedido em 20/10/2019, https://msu.edu/~luckie/segway/i167/i167.html [2] Donnici, Giampiero, et al. "TRIZ method for innovation applied to an hoverboard." Cogent Engineering 5.1 (2018): 1524537. [3] OSOYOO, smart balancing car announced in amazon, acedido em 20/10/2019, https://www.amazon.com/OSOYOO-Balancing-Educational-Programmable-Bluetooth/dp/B07G491291 [4] Juang, Hau-Shiue, and Kai-Yew Lurrr. "Design and control of a two-wheel self-balancing robot using the arduino microcontroller board." 2013 10th IEEE International Conference on Control and Automation (ICCA). IEEE, 2013. [5] Ghani, Nor Maniha Abdul, Faradila Naim, and Tan Piow Yon. "Two wheels balancing robot with line following capability." World Academy of Science, Engineering and Technology55 (2011): 634-638. [6] Eletrofun, regulador de tensão 7805, acedido em 27/12/2019, https://www.electrofun.pt/744-large_default/regulador-de-tensao-7805.jpg [7] Newegg, L298N Dual Full Bridge Driver Multiwatt15 Integrated Circuit L298 IC, acedido em 27/12/2019 https://c1.neweggimages.com/NeweggImage/ProductImageCompressAll1280/A4W3_130734047698432156w8p3isDEMy.jpg [8] Eletrofun, Motores DC, acedido em 27/12/2019, https://www.electrofun.pt/7923-large_default/motor-dc-12v-dc-180ma-11500rpm.jpg [9] Eletrofun, Módulo Acelerómetro E Giroscópio 3 Eixos 6DOF GY-521 MPU-6050, acedido em 18/10/2019, https://www.electrofun.pt/123-large_default/modulo-acelerometro-giroscopio-mpu-6050.jpg [10] FilipeFlop, Controlando LCD 16x2 com arduino, acedido em 25/10/2019, https://www.filipeflop.com/blog/controlando-um-lcd-16x2-com-arduino/ [11] Mercado Livre, Microcontrolador Atmega88, acedido em 22/11/2019, https://http2.mlstatic.com/microcontrolador-atmega88pa-pu-atmega88-atmel-avr-D_NQ_NP_762553-MLB31136728588_062019-F.webp [12] Peter Fleury, Avr software, acedido em 10/11/2019, http://homepage.hispeed.ch/peterfleury/avr-software.html |
|||||||||||
|
|
|||||||||||