Pessoal,

Estou construindo encoder´s IR para medição de rotação de dois micro-motoredutores de um robô de duas rodas.
Estou a meses me debatendo com interrupções indevidas geradas no Arduino.

O projeto:

A leitura é feita nas rodas, através de codewheel impresso em laser.
Estou utilizando o TCRT5000 (pack reflexivo) para os sensores. Com eles consigo um sinal senoidal bastante boa, quase perfeita, oscilando aproximadamente entre 0,4 e 3,9 volts. A frequência é baixa (1 a 20 Hz).

O sinal gerado pelo Receptor do TCRT passa por um Schmitt Trigger (74HC14) e a onda quadrada gerada vai para o pino do Arduino.

O problema é na leitura do tempo entre pulsos no Arduino.

Utilizando "pooling" (lógica no loop()) não ocorrem problemas e consigo obter a leitura necessária, embora a técnica deixe a desejar em performance geral do robô.

Utilizando interrupção Externa ocorre detecção de interrupções indevidas. Utilizando interrupção Pin Change, a quantidade é menor, mas também ocorrem.

Porque interrupções Indevidas ?

Bem, com esse problema eu acabei comprando um Osciloscópio USB (20 MHz) e consigo com ele detectar que nos
momentos em que não há transição de estado no pino do Arduino ocorre interrupção mesmo assim, às vezes duas em um meio período do sinal.

Já utilizei várias técnicas para delimitar esse problema, sendo a mais simples e direta (na minha opinião) a seguinte:


. Na rotina de interrupção (ISR) eu apenas inverto a condição de uma variável booleana.
. No loop() eu analiso esta variável e aciono ou não uma saída digital do Arduino descarregando ao GND através de um resistor de 10k. Leio a forma de onda deste pino com o osciloscópio.

Assim consigo comparar o sinal gerado pelo TCRT, na saída do 74HC14, na entrada do pino de interrupção do Arduino e nesta saída digital que representa a informação houve ou não interrupção.

Só ocorre problema detectável - por esse osciloscópio - nesta saída digital! Todos os demais sinais estão conforme esperado.

Já utilizei direto no robô e em protoboard, Arduinos Uno, Nano e Mega. Todos apresentam o mesmo problema.
Já utilizei sensores IR como o TCRT, bem como TIL´s e uma Chave (de interrupção do feixe).
Já utilizei cabo blindado entre a placa de IR e o Arduino, com capacitor de 100nF e até 1uF descarregando o sinal no GND e nada. No caso do uso de capacitores, ocorre um pequeno arredondamento da forma de onda, mas continua sendo detectado normalmente pelo Arduino.

Considerando que o problema seja de algum transiente gerado no circuito - preciso girar um motor acionado por PWM para que o sensor IR possa gerar o sinal necessário - pergunto o que mais poderia fazer para tentar resolver esse drama ?

No motor estou utilizando capacitores de 100nF na sua alimentação, de cada fase da alimentação para GND e de sua carcaça para GND. Estou utilizando pinos para o PWM em 1KHz para frente e 500 para trás. Não há mudança do problema com isso.


Não sei se ficou claro a explicação. Para quem leu até aqui me desculpe a extensão do texto. O fato é que já procurei na internet inteira e não encontro ninguém relatando problema semelhante, pelo menos com uma "solução" para tentativa. A única informação boa que encontrei, mas mesmo assim apenas uma afirmação, é de que as interrupções do Arduino são "muito sensíveis".

Vejo em materias e vídeos na internet que inúmeras pessoas utilizam essa tecnica com aparente sucesso, portanto seria essa sensibilidade tão elevada assim ?

Já ia me esquecendo, mas dos meses em que me debato com isso, me preocupei muito com um provável transitente gerado no receptor do TCRT. Fiz inúmeros experimentos travando uma condição anormal, se existisse, e concluí que esta ppossibilidade esta descartada, pelo menos na bancada.

É problema de ruído ou pode ser alguma outra coisa ?

Idéias são muito bem vindas,

Obrigado,

Wilmar

Exibições: 8034

Anexos

Responder esta

Respostas a este tópico

Qual é a base de tempo das formas de onda enviadas?

A idéia é colocar um delay enquanto o sinal esta mudando de estado.

Quais delays usou ?

Uma pergunta = motores geram muitos ruidos. Já "scopou" os sinais dos motores?

A frequência do sinal é de aproximadamente de 1 a 17 Hz em função do codewheel (34 "furos") que estou utilizando para obter um bom sinal básico. 

A utilização de um delay que mascarasse uma possível interrupção indevida, servindo como debouncing é complicado porque admitindo que eu chaveasse constantemente a interrupção de RISING para FALLING a cada período, mesmo assim eu teria um ciclo de interrupções a cada 500mS na menor rotação. Como não pude perceber uma tendência das interrupções indevidas - logo após uma verdadeira, p. ex - o delay teria que ser de algumas centenas de mS e isso impossibilita que eu rode dois PID´s rápidos (< 75 mS) neste Arduino, motivo básico dos encoder´s, além de outras lógicas para manobras.

Por outro lado, a incidência do problema é maior quanto maior é a rotação dos motores. Na menor rotação ela ocorre muito esporadicamente, enquanto na maior (100% nos testes) não passa dez pulsos para erro em média, às vezes havendo dois até três interrupções em um período. Há um aspecto interessante aqui, porque a 100% do PWM praticamente (teoricamente) não há pulsos, devendo portando ter menos ruído, e isso não minimiza o problema.

Assim, talvez um tratamento diferenciado nos delays pode se tornar mais aceitável.

Vou fazer uns testes amanhã com essa idéia.

Aproveitando, quando em sua resposta você perguntou se eu havia checado se haviam outras interrupções habilitadas eu respondí que sim porque tstei um noInterrupts() no setup() e só depois fiz a definição das interrupções. Como isso não fez diferença deixei de fazer isso. Pensando agora, me parece não ser a mesma coisa que checar realmente as interrupções habilitadas. Como não manjo nada de Assembler para ATmega (parei com isso na época do Z80) como poderia fazer isso ?

Wilmar estou interessado nessa assunto pois é novo para mim no Arduino.

Duvidas:

- usa motores DC - tem diodo para suprimir força contra eletromotriz? Qual driver esta usando?

- seu sensor IR de rotação esta protegido contra luz externa ? Lampadas fosforescentes podem interferir.

(apague a luz para testes)

E estava me esquecendo do Analisador Lógico Arduino -( se tiver um segundo Arduino) para fazer uma amostragem mais expandida.

http://labdegaragem.com/profiles/blogs/tutorial-analisador-l-gico-c...

Use dois canais no analisador - um com o do sensor e outro do pino de teste.

Estava pensando sobre a interferência de outras interrupções.

Se esta usando somente o programa que enviou, não acredito que seja o caso.

Achei que pudesse ser uma interrupção da serial.

Sim, na ponte H há diodos para proteção.

A que estou utilizando eu construí com dois L298, utilizando os "dois canais" de cada L298 para cada motor.

Já utilizei desses xing ling em rotações menores, mas com esses motores esquenta bastante.

Aproveitando, na resposta anterior sobre a análise do sinal do PWM posso ter viajado um pouco. Fiz umas leituras agora, e tanto com capacitores no motor quanto sem não há mudança detectável pelo meu osciloscópio. Coloquei um print screen como anexo. Não é propriamente uma onda quadrada! Será que tem algo estranho ai ?? A base de tempo está em 0,192 mS/div.

Quanto à uma possivel interferência luminosa no sensor IR, foi minha primeira preocupação quando os problemas começaram. Fiz uma plaquinha com possibilidade de variar a tensão no emissor e no receptor e apos trocentos testes achei uma configuração que praticamente não é sensível à luz solar nem à uma luminária fluorescente bem encima da bancada (30 cm). Desde que o sol não incida diretamente no sensor ele é "imune".

Testei isso deixando o sensor por horas apontado para uma janela com incidência de sol, conectado em um Arduino que faria um latch do sinal gerado por uma interrupção externa, tocando uma buzinha. Não ocorreu interferência!. Também já enclausurei o protótipo de testes contra luz e nada. Cheguei a conclusão de que a interferência não é de origem luminosa.

Estou utilizando para o TCRT5000, 220R no emissor e 4k7 no fototransistor. Me parece a melhor configuração, não forçando demais o emissor, que parece pode perder emissividade depois de um tempo à correntes maiores.

Eu ainda não mergulhei no seu post sobre o Analisador Lógico com Arduino, mas vou fazê-lo com certeza.

Nos sketchs em que uso a serial para mostrar os tempos entre pulsos das interrupções, aparentemente não ocorrem maiores problemas além dos detectados no osciloscópio.

Anexos

Não acredito que o sinal negativo do PWM seja a causa. Veja que a tensão negativa deve ser o corte da proteção  dos diodos...

Vamos dormir, amanhã vou pensar sobre isso...

Tenho um scope DSO Tektronix TBS 1062 (60 MHz). 

Talvez até eu monte algo só  para teste.

Ok Gustavo, é uma boa hora para nanar mesmo.

Dar um tempo nos problemas é uma excelente técnica para resolver problemas!.

Até amanhã.

Wilmar , tem como enviar o circuito do sensor de rotação e a ligação com o Arduino?

Se nada resolve, pode ser problema nesse circuito...

Outra sugestão : desative os motores e conecte seu disco otico com os sensores em uma furadeira com controle de rotação, para confirmar que o problema não é causado por interferência dos motores.

Gustavo,

O circuito que fiz em Fritzing está extremamente sofrível porque construí a plaquinha em uma PCB universal e só fiz mesmo o circuito para estudar o layout. Ela está no anexo, mas não leve muito a sério.

Basicamente o circuito se resume à polarização do emissor e do fototransistor como esse:

No caso do pack reflexivo TCRT5000 estou usando 220R para o emissor e 4K7 no fototransistor.

Com esses valores, consegue-se um bom sinal à aproximadamente 3 mm do codewheel.

O sinal de saída (senoidal) passa em um Schmitt Trigger (usei o 74HC14 - inversor) sendo sua saída conectada direto no pino do Arduino (D2 ou D3 para interrupção externa ou praticamente qq um para a Pin Change).

Eu testei com TIL´s 32 e 78 com bons resultados tb, embora sejam bem maiores que o TCRT. 

A maior dificuldade em conseguir um bom sinal senoidal é na qualidade do codewheel (usei esse programa aqui) imprimindo à laser em papel couchê, e em sua centralização na "roda". Também o número de "furos" em função do diâmetro é importante. Eu estou utilizando no robô 34 "furos" em diâmetro de 2 pol, mas o ideal mesmo seriam mais "furos" e para isso, seriam necessário um diâmetro maior.

No Arduino, há ainda um potenciômetro para variação de rotação, sendo o motor acionado por ponte H (simples).

Quanto a sua sugestão de utilizar uma furadeira, especificamente a furadeira não dá certo porque a rotação máxima dos meus motores são de 80 rpm, mas eu tenho como rodar o robô com a detecção do IR em outro Arduino.

Essa basicamente foi uma dica do colega Eduardo propondo utilizar um 555 para gerar o sinal quadrado para as interrupções. Eu já fiz isso a algum tempo atrás, e também já utilizei dos Arduinos, um para o motor e outro para o IR / interrupções e em ambos os casos o problema não foi resolvido. Só que no momento destes testes eu não tinha o meu osciloscópio meia-boca, então não sei como estava a qualidade dos sinais.

Hoje eu trabalhei pouco nisso, basicamente estou substituindo vários capacitores de poliéster utilizados para filtro por cerâmicos, principalmente nos motores.

Concluída essa substituição, vou refazer esse teste com o 555, porque nele não há motores / ponte H / PWM, então onde estaria sendo gerado o ruído ?? Na minha plaquinha é uma opção, mas eu já rechequei ela várias eles, e fiz outras para um comparador de tensão p. ex. Na verdade dá até para ligar o fototransistor direto no Arduino, porque todas as entradas dele têm um schmitt trigger! Como apareceu esse problema, eu acabei embarcando nas plaquinhas...

Anexos

Wilmar bom dia, 

Montei um LM555 para teste - R1 = 1K, R2 = 220K e C1 = 0,47uF => Freq = 4,66 Hz

http://labdegaragem.com/profiles/blogs/ci-555-modo-astavel-oscilador

Rodei o Sketch que enviou. Montei um Led + resistor no pino (8) de feedback.

Veja minhas medições com o scope. Estão perfeitas !

CH1 - saida do LM555 (pino 3) 

CH2 =  pino (8) de feedback

Isto pode ser um problema no seu chip 74H14 (troque-o).

Aterre todas entradas sem uso.

Qual alimentação do crcuito e do Arduino esta usando?

Recomendo que use o Analisador lógico com Arduino para ter certeza que esta ainda com problema. 

Gustavo,

Muito obrigado pela força!.

Agora fiquei com esperanças... Vou refazer esse teste com o 555 e depois ir agregando meus componentes do robô (o DUWI). Já faz algum tempo que fiz isso, e sinceramente não me lembro mais as condições do teste.

Eu utilizo alimentação por uma LIPO 3S (12,4 volts) para os motores e reduzo para 5V em um 7805 que está em uma plaquinha que eu chamo de expansão porque tem vários componentes nela. O 7414 está separado em outra plaquinha utilizando os 5V da expansão, aliás todo 5V para o robô é provido por ela.

 

Hummm:

.Eu não aterrei todas as entradas do 7414

.Não o substituí para verificação

Eu já baixei tudo para rodar o Analisador Lógico com Arduino. talvez coloque ele para rodar agora para estes testes.

De novo muito obrigado pelas dicas Gustavo.

Hoje estou com mais tempo e daqui a pouco coloco algum resultado aqui.

Vai dar certo!

Boa sorte.

PROGRESSO!
Mas não sei se achei o real problema.


Eu demorei muito mais que gostaria para dar uma resposta dos testes que me foram remcomendados neste fórum, por falta de tempo, falta de componentes, lojas fechados neste final de semana, um curto-circuito que danificou uma plaquinha do meu robô (o DUWI), entre outros motivos.

Contudo, obtive progresso. Vou relatar mais ou menos detalhadamente os fatos para ajudar outras pessoas com problemas parecidos.


O que fiz:

Primeiro desmontei quase 100% dos componentes que estavam integrados no chassis do robô. A parafernália está no anexo 1.


Depois montei em uma protoboard um oscilador com um NE567 que permitia variar a frequência de 1 a aproximadamente 90 Hz e o utilizei como simulador do sinal tratado do encoder, como o colega Gustavo já havia feito - e me motivou a começar tudo de novo, pois eu já havia feito isso a algum tempo atrás.

Depois fui incluindo os componentes do robô (basicamente plaquinhas PCB) um a um, as que estavam energizadas nos últimos dias e testando com a frequência do oscilador em 1, 20 e 90 Hz (a frequência máximo do DUWI será de 20 Hz).

Por último conectei a ponte H para 4A que fabriquei, conectei um dos motores do robô nela e o fiz girar pelo PWM.

Hiii, apareceu o problema (interrupções indevidas).


Hummmm, hummmm ....


Depois de um tempo com fuça daqui, fuça dali, PUM, deu um curto-circuito.
Eu acho que um cabinho solto encostou na ponte H. O fato é que o regulador 7805 da placa de expansão que provê os 5 volts para todo o robô (inclusive para a ponte H) morreu.

Isso foi no sábado, eu não tinha um substituto. Resolví colocar um LM317 no seu lugar. Só que a pinagem é diferente e deu um trabalhão danado, uma vez que o espaço disponível nesse placa é inexistente.

Depois de concluir a modificação percebí que o curto ocasionou algum problema nessa placa. Ela permanece em curto!. Depois de horas tentando achar o problema desistí, pois já estava perdendo a paciência.

Ahummm ahummmm.... Resolví utilizar outra fonte de 5 volts da fase inicial do DUWI que tem um 7805, abandonando temporariamente a placa em uso.

Voltei aos testes, utilizando essa fonte de 5 volts alimentada por uma fonte de PC modificada que tem proteção.
Sim, eu não instalei os fusíveis do robô na montagem na bancada e estava utilizando uma LIPOS 3S!.

Voltando a operar, voltei com o problema motivo disso tudo, as interrupções indevidas.

Fuça daqui, fuça dali... Pensa, pensa. Depois de varias horas (já na madrugada de domingo) tive uma luz: o problema não estava exatamente igual quando aparecia no robô integrado. Agora o Arduino Nano perdia inúmeras interrupções em seguida (dezenas delas). O problema inicial eram interrupções demais (indevidas) não de menos !!!

Hoje fui às compras: 555, capacitores, uma plaquinha PCB universal entre outras coisas.
Construí um oscilador com o 555 que permite ajuste de 1 a 50 Hz aprox., e coloquei nela os resistores para descarga da saída do Arduino utilizado para monitorar as interrupções (10K), tudo soldado.
Utilizei pinos (quadrados) de barras de pinos cortada com conectores Modu. Antes em uma protoboard eu estava utilizando aqueles fiozinhos vagabundos, com pontas redondas. A luz que ví foi a de mau contatos!.

Concluída essa plaquinha e com toda a parafernália montada voltei aos testes, já na noite de segunda-feira.

MARAVILHA!

Conectei os dois motores e cheguei a conectar a plaquinha dos encoders na saida do oscilador e da saída do 74HC14 dela ao Arduino (isso para conectar e energizar tudo que estava utilizando até então).
Variando o PWM de 0 a 100% (onde um dos motores tem uma parcela a menos que o outro, um está em 1kHZ e outro em 500Hz, e variando o oscilador de 1 a 50 Hz tudo funcionou mil maravilhas.

Eram aqueles fiozinhos benditos os culpados, talvez minha protoboard!.
Cheguei a isso, porque a única coisa do robô que não estava soldado ou com conectores Modu eram os resistores para  as saídas de monitoramento das interrupções do Arduino!!!!

Daí instalei os encoders em uma mesma roda, os conectei à sua placa, desliguei o oscilador 555 e mantive na sua plaquinha apenas o feedback das interrupções. Foto no anexo 2.

MARAVILHA DE NOVO!!!

Testei essa última montagem por horas. Funciona perfeitamente, sem nenhuma interrupção indevida detectada.
Como havia lido, as interrupções do Arduino são muito sensíveis e aparentemente o mal contato desses cabinhos na protoboard pode ter gerados as interrupções "extras".

Essa montagem está no anexo 2.
No anexo 3 está um printscreen do osciloscópio com os sinais do encoder (apenas um conectado no Arduino) e das interrupções (feedback) geradas.


Para ser mais exato na avaliação, a outros dois fatores a considerar:

1 - Eu havia substituído vários capacitores de poliéster utilizados como filtro por cerâmicos, principalmente nos motores, na placa de expansão (fonte 5v), ponte H, Arduino Shield (onde está instalado o Nano e alimenta algumas outros componentes. Como para isso fui obrigado a retirar essas placas do chassi, eu não retestei pois já embarquei nos testes mais profundos;

2 - a Placa de Expansão que queimou não foi mais utilizada nos testes, pois não conseguí consertá-la. Essa placa é fundamental para o robô, pois além de entradas/saídas extras (3x PCF 8574) tem ainda um magnetômetro, um acelerômetro e um IR Remote, além de ser a "central" de conectores para comunicação I2C.


Amanhã (hoje) vou tentar consertar a placa de expansão para tirar a dúvida sobre ela.

Testar se a substituição dos capacitores melhorou alguma coisa é dificílima, porque eu teria de resubstituí-los.

Teoricamente, poderia essa substituíção de poliéster por cerâmicos ter filtrado os problemas ??

Assim que resolver a questão com a placa de expansão posto os resultados.

Depois, não sei, começo a remontar tudo ou é mais prudente fazer algum outro teste ? Qual ?

Anexos

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço