Wednesday 25 October 2017

Filtro médio móvel arduino


Introdução Uma das principais aplicações para a placa Arduino é a leitura e registro de dados de sensores. Por exemplo, um monitora a pressão a cada segundo do dia. Como altas taxas de amostragem geralmente gera picos nos gráficos, também se deseja ter uma média das medições. Como as medições não são estáticas no tempo o que muitas vezes precisamos é de uma média de corrida. Esta é a média de um determinado período e muito valioso quando se faz análise de tendências. A forma mais simples de uma média em execução pode ser feita por um código que se baseia na média anterior: Se não se deseja usar matemática em ponto flutuante - como isso ocupa a memória e diminui a velocidade - pode-se fazer o mesmo completamente no domínio inteiro. A divisão por 256 no código de exemplo é um deslocamento-direito 8, que é mais rápido do que digamos divisão por, e. 100. Isso é verdade para cada poder de 2 como divisor e um só deve ter cuidado a soma dos pesos é igual ao poder de 2. E, claro, deve-se tomar cuidado não há transbordamento intermediário (considere usar unsigned longo) Se você precisar Uma média de execução mais precisa, in concreto das últimas 10 medições, você precisa de uma matriz (ou lista vinculada) para mantê-los. Esta matriz age como um buffer circular e com cada nova medição a mais antiga é removida. A média de execução é calculada como a soma de todos os elementos divididos pelo número de elementos na matriz. O código para a média em execução será algo como isto: Desvantagem deste código é que a matriz para armazenar todos os valores pode se tornar bastante grande. Se você tem uma medição por segundo e você quer uma média de execução por minuto que você precisa de uma matriz de 60 uma média por hora precisaria de uma matriz de 3600. Isso não poderia ser feito desta maneira em um Arduino como ele só tem 2K de RAM. No entanto, através da construção de uma média de 2 estágios que pode ser abordado muito bem (renúncia: não para todas as medições). No código psuedo: Como uma nova matriz estática interna é necessária para cada função runningAverage, este grita para ser implementado como uma classe. Biblioteca RunningAverage A biblioteca runningAverage cria uma classe da função acima para que ela possa ser usada várias vezes em um sketch. Desacopla a função add () e avg () para ser um pouco mais flexível, e. Um pode chamar a média várias vezes sem adicionar uma coisa. Observe que cada instância da classe adiciona sua própria matriz para realizar medições e que isso adiciona até o uso de memória. A interface da classe é mantida o menor possível. Nota: com a versão 0.2 os nomes dos métodos são todos mais descritivos. Uso Um pequeno esboço mostra como ele pode ser usado. Um gerador aleatório é usado para imitar um sensor. Em setup () o myRA é limpo para que possamos começar a adicionar novos dados. Em loop () primeiro um número aleatório é gerado e convertido em um flutuador a ser adicionado ao myRA. Em seguida, o runningAverage é impresso para a porta serial. Pode-se também exibi-lo em algum LCD ou enviar mais ethernet etc Quando 300 itens são adicionados myRA é limpo para começar de novo. Notas Para utilizar a biblioteca, crie uma pasta no SKETCHBOOKPATHlibaries com o nome RunningAverage e coloque o. h e. cpp lá. Opcionalmente, faça um subdiretório de exemplos para colocar o aplicativo de exemplo. Histórico 2017-01-30: versão inicial 2017-02-28: fixa destrutor em falta no arquivo. h 2017-02-28: construtor padrão removido 2017--. Adicionado fillValue () refactored para publicação 2017-07-03: adicionado código de proteção de memória - se matriz interna não pode ser alocada tamanho Torna-se 0. Isso é para resolver o problema descrito aqui - forum. arduino. cc/indextopic50473.msg1790086msg1790086 - Todo Test extensivamente. Classe de modelo RunningAverage. h RunningAverage. cppTutorial: Potenciômetros com Arduino e filtragem Neste blogpost iremos analisar o que é um potenciômetro e como eles funcionam, como conectá-lo a um Arduino, bem como descrever um problema comum no que diz respeito ao uso do potenciômetro E uma solução para esse problema. O que é um potenciômetro Um potenciômetro, doravante referido como um potenciômetro. É uma resistência variável. É um componente eléctrico com três terminais (isto é, pinos ou pernas): um para a tensão de entrada (por exemplo 5V), um para a tensão de saída (por exemplo GND) e um para pegar o valor do pote (chamaremos isto o limpador). Mecanicamente falando, panelas são fisicamente ajustadas geralmente usando os dedos. Os potes rotativos e lineares são comuns. Um potenciômetro giratório e linear (fonte: Wikipedia) Os potenciômetros são usados ​​muito em todos os tipos de dispositivos elétricos. Botões de volume, dimmers de luz e faders em misturadores de áudio são muitas vezes potes. Eles também vêm em versões digitais e até motorizados, mas aqueles estão fora do escopo deste post. Se você deseja controlar a velocidade do seu motor elétrico, a posição de seu servo, o brilho do LED, o corte do filtro em seu sintetizador, o ganho em seu amplificador de guitarra ou milhares de outras coisas interessantes em seu próprio sistema embutido, um pote pode ser a solução para voce. A teoria Para uma introdução à teoria elétrica, dê uma olhada neste post que escreveu um tempo atrás, onde nós explicamos os fundamentos, como tensão, resistência e corrente, bem como a relação entre estes. Então, o que está acontecendo em um circuito com um pote é basicamente divisão de tensão na prática. R1 e R2 estão dentro do próprio recipiente. (Fonte: Wikipedia) Nos esquemas acima, os resistores R 1 e R 2 fazem parte do próprio pote. R L é a resistência da carga (um motor, um LED ou qualquer outro). Quando você gira ou desliza o pote, você vai mudar os valores de R 1 e R 2. Movendo o pote de uma maneira irá reduzir R 1 e aumentar R 2. e vice versa. Isso resulta em vários valores de tensão no limpador (o que vai para R L nos esquemas acima). O valor de tensão em si pode ser calculado usando a seguinte equação: onde V L é a diferença de tensão entre o limpador e o pino de saída, e V S é a diferença de tensão entre o pino de entrada e de saída. Para simplificar isso um pouco: se o pino de saída está conectado a GND, você pode simplesmente dizer que VL é a tensão no limpador e VS é a tensão no pino de entrada (e então apenas ignorar a 8220 diferença de tensão8221 mumbo jumbo desde GND é definido Como 0V). O Pote e o Arduino 8211 um Exemplo Basta com a teoria, let8217s colocar as coisas em funcionamento com um exemplo O Hardware No exemplo a seguir we8217ve usou um pequeno pote de plástico de 10K para breadboard, uma breadboard. Alguns fios de salto (estes são excelentes para esta finalidade) e, claro, um Arduino (neste caso, um Leonardo). Deixamos 5V ir para um dos pinos nas laterais do pote e GND para o outro. O médio precisa ir para um dos pinos ANALOG IN no Arduino, neste caso A0. E that8217s ele O circuito está acima e funcionando O fio vermelho: 5V, fio preto: GND, fio amarelo: sinal do limpador ao ADC. ADC (Conversor Analógico-Digital) O sinal do pote é analógico, mas queremos que ele seja digital para que possamos ler o valor na tela. Arduino tem um built-in ADC (conversor analógico-digital) que cria uma representação digital do sinal analógico. Quanto maior a tensão de entrada, maior o valor digital. Arduino8217s ADC leva em 0 a 5 volts e tem uma resolução de 10 bits que permite a saída de 1024 valores digitais. Para resumir: 0 volts é equivalente a um valor digital de 0 e 5 volts é equivalente a um valor digital de 1023. Você pode ler mais sobre o Arduino8217s ADC aqui. O Software A maneira mais básica de ler o valor do pote é imprimir o valor digital para o monitor serial, de modo que o que vamos fazer. O fluxo deste programa simples será assim: Inicializar variáveis ​​globais. Configure o módulo serial. O laço Leia a tensão do pote e execute-o através do ADC. Escreva o valor digital do pote para o monitor serial. Espere 50ms antes de repetir. Abaixo está o código we8217re rodando no Leonardo: Quando o código estiver funcionando, abra o Monitor Serial no IDE do Arduino para ver a alteração do valor do pote ao girar o botão. Lembre-se de definir o baudrate para o mesmo valor que na inicialização serial no software (115200 no nosso caso) A Common Problem and Filtering Se o seu software deve reagir significativamente às mudanças no pote (por exemplo mudar um estado principal) você vai ter Um mau momento. A razão para isto é que enquanto você não está tocando o pote, os valores podem mudar de qualquer maneira. E quanto maior for a resolução do seu ADC, mais provável é que você encontre esse ruído de medição. A razão para esta questão é que o pote é continuamente ajustado e que muitas vezes é posicionado no meio de dois valores digitais. Lembre-se que o mundo real não é ideal, tão pequenas mudanças inevitáveis ​​na tensão de ruído é suficiente para bater de um lado para outro entre dois ou mais valores digitais. Um par de soluções Então, como lidar com isso Em primeiro lugar, don8217t projetar seu programa para que uma pequena mudança no pote faz algo importante. Em segundo lugar, para reduzir esse ruído de medição, você pode tentar adicionar filtragem de baixa passagem simples no software. Um algoritmo de média móvel será muitas vezes suficiente. Vamos implementar um algoritmo de média móvel exponencial, doravante denominado como EMA. Para suavizar o sinal neste exemplo. Sinta-se livre para experimentar alguns dos outros algoritmos de média móvel também. O algoritmo EMA é o seguinte: onde S t é o resultado da EMA no tempo t. Y t é a medida do pote no tempo t. E é um coeficiente no intervalo lt0,1gt que decide quantas amostras o algoritmo EMA deve levar em conta. Um baixo será muito lento para mudanças rápidas de entrada e levar em consideração muitas amostras. A alta será rápida, mas a média de menos amostras. Você pode olhar como um tipo de uma freqüência de corte em um filtro passa-baixa. Uma visualização de como a EMA opera. As colunas ao longo do eixo X são as amostras com a mais recente à esquerda. A altura das colunas no eixo Y é o 8220 peso8221 de cada amostra, i. e. como 8220importante8221 cada amostra é quando se calcula o EMA. (Fonte: Wikipedia) Here8217s o código final com o EMA: Experimente com diferentes valores de para ver a diferença de velocidade quando rapidamente mudar a posição do pote. Uma breve conclusão Esperamos que este pequeno tutorial tenha sido útil para você. Potenciômetros são super úteis em sistemas embarcados e muito divertido de brincar com. Usá-los para controlar qualquer you8217d como Related ArticlesIm não certeza da solução correta embora desde soma a média de cada amostra iria introduzir uma quantidade razoável de erro de arredondamento. Hmm. Gostaria de saber se seperating a parte fracionária de toda a parte iria ajudar. Divida a parte inteira de cada número pela contagem. Manter três somas correntes: 1) A média das partes inteiras, 2) O restante de cada divisão, e 3) A parte fracionária de cada número. Cada vez que a parte inteira de um número é dividida, o resultado da parte inteira é adicionado à soma corrente média e o restante é adicionado à soma corrente restante. Quando a soma corrente restante obtém um valor maior ou igual à contagem, a sua divisão pela contagem com o resultado da parte inteira adicionada à soma média corrente e o restante adicionado à soma restante em curso. Também, em cada cálculo, a parte fracionária é adicionada à soma de corrida fracionária. Quando a média é terminada, a soma corrente restante é dividida pela contagem e o resultado é adicionado à soma média corrente como um número flutuante. Por exemplo: Agora o que fazer com a soma de execução fracionada. O perigo de estouro é muito menos provável aqui, embora ainda possível, então uma maneira de lidar com isso seria dividir a soma de execução fracionária pela contagem no final e adicioná-lo ao nosso resultado: Uma alternativa seria verificar a execução fracionária Soma em cada cálculo para ver se ele é maior ou igual a contar. Quando isso acontece, basta fazer a mesma coisa que fazemos com o restante executando soma. Excelente Jomit Vaghela 6-Mar-07 20:00 Eu gostei do que você disse pequenos trabalhos rapidamente se transformar em grandes empregos. Pensar em otimização durante a codificação é uma boa prática. Grande esforço e explicação, Obrigado Mike DiRenzo 5-Mar-07 15:26 Esta é a primeira vez que respondi a um de seus artigos. No entanto, sou um leitor muito ávido. Enquanto na faculdade, eu tinha que computar médias móveis ponderadas e simples também. Heck, eu mesmo tive que criar alguns dos meus próprios algoritmos de média móvel em uma implementação de ERP personalizado há algum tempo com base em algumas das mesmas fórmulas que eu aprendi em operações 101. Mas esta implementação, usando Generics, supera em muito qualquer coisa em termos de otimização, Simplicidade, e frescura direita darn. Muito obrigado por isso. Um de seus muitos fãs, Em silêncio e silêncio, a verdade fica clara. Ewma gobgob 5-Mar-07 4:30 Se você tentar calcular uma média móvel simples, você tem que manter uma coleção, o que é bastante complexo para uma tarefa tão simples. Como sobre o uso de um ewma Suas 2 linhas de código, muito mais simples. Alfa exp (-elapsedTimeSinceLastValue) ewma alfa ewma (1-alfa) newValue Re: ewma Marc Clifton 5-Mar-07 4:47 Como sobre o uso de um ewma Ideia interessante. Para os leitores que não sabem o que é um ewma, é um Exponential Weighted Moving Average. As pessoas são apenas notoriamente impossíveis. --DavidCrow Theres NENHUMA desculpa para não comentar seu código. - John Simmons / programador proscrito As pessoas que dizem que refatorarão seu código mais tarde para torná-lo bom não entendem refatoração, nem a arte eo ofício de programação. - Josh Smith Re: ewma pwasser 5-Mar-07 12:21 Uma estimativa da média móvel se o tamanho do bin para a média móvel for n pode ser obtido por: NewAverage (((n-1) OldAverage) newValue) / n Isso funciona uma vez que a caixa está cheia (número de amostra n). O compartimento parcialmente cheio é muitas vezes tratado usando um valor de semente para a média móvel inicial (OldAverage) e, em seguida, usando esse cálculo. Isso pressupõe uma distribuição normal de valores etc. Você foi ocupado Colin Angus Mackay 4-Mar-07 11:37 Postando dois artigos nesta noite. Grande trabalho eu não sei como você faz isso. Ive tem cerca de 4 ou 5 artigos metade terminou e eu só nunca parecem encontrar o tempo para completá-los. Bem. Talvez se eu ficasse fora do salão, eu conseguiria. Re: Youve sido ocupado Marc Clifton 4-Mar-07 13:25 Colin Angus Mackay escreveu: Postando dois artigos esta noite. Grande trabalho Obrigado, eu estava realmente escrevendo o artigo sobre a média correndo e percebi que a lista circular seria realmente um artigo stand-alone realmente bom. Além disso, eles são artigos leves. Posso fazer isso rapidamente. É apenas difícil de pensar em coisas úteis, mas simples. Acontece que eu precisava dessas duas classes de qualquer maneira. As pessoas são apenas notoriamente impossíveis. --DavidCrow Theres NENHUMA desculpa para não comentar seu código. - John Simmons / programador proscrito As pessoas que dizem que refatorarão seu código mais tarde para torná-lo bom não entendem refatoração, nem a arte eo ofício de programação. - Josh Smith Re: Youve sido ocupado JeffPClark 8-Mar-07 0:07 Pelo que eu li de Marc, ele provavelmente tem um programa que pode examinar um pedaço de código e explicar os detalhes intrincados, em seguida, publicá-lo diretamente para o projeto de código . Jeff Clark Arquiteto Arquiteto JP Clark, INC. Columbus, Ohio Última Atualização: 12-Out-16 1:29 Geral Notícias Sugestão Pergunta Erro Resposta Joke Praise Rant Admin Use CtrlLeft / Right para mudar Mensagens, CtrlUp / Down para alternar segmentos, CtrlShiftLeft / Direita para mudar pages. Timo, eu vi que você encontrou uma solução parcial para o seu problema (citação: não há gravidade que mantenha o giroscópio na posição certa). Eu gostaria de elaborar porque há maneiras de obter resultados razoavelmente bons de um giroscópio apenas. Eu não sei se será bom o suficiente para a sua aplicação. Aqui estão os resultados que eu tenho usando o mesmo hardware que você: robokitchen. tumblr / post / 68625623585 / imu-com-giroscópio-só-i-testado-os-três-eixos. Neste vídeo eu não estou usando o acelerômetro em tudo. Há dois pontos que poderiam ajudá-lo a obter melhores resultados: 1) A menos que seu sensor permanece totalmente horizontal você não pode obter a rotação do eixo z usando esta fórmula: Para explicar por que, imagine isso: se o seu giroscópio girou 90 graus em torno do eixo x então 90 graus em torno do eixo z, você não obteria o mesmo resultado como se girasse apenas 90 graus em torno do eixo z. Isso significa que você deve calcular a rotação em torno de todos os eixos e, em seguida, extrair a rotação do eixo z. Se você não usar os eixos xey, seus resultados serão incorretos (a menos que seu sensor permaneça totalmente horizontal). Uma maneira eficiente de calcular a rotação em torno de todos os eixos é usar quaternions. Há muito a dizer sobre quaternions, então eu deixá-lo fazer sua própria pesquisa e fazer mais perguntas, se necessário. 2) Depois de usar todos os 3 eixos, ainda haverá uma deriva estática. Isso ocorre porque o giroscópio não vai ler um perfeito 0 mesmo quando ele não se move. Para melhorar a situação, você poderia calibrar o giroscópio. Uma maneira fácil de calibrar é ler um grande número (100) de valores quando o giroscópio não está se movendo, calcular a deriva média e subtraí-la de suas medidas quando o giroscópio está se movendo. Ainda haverá uma ligeira deriva depois disso, mas não tão ruim quanto o que você pode estar experimentando agora. Aqui estão os melhores resultados que eu tenho, usando o giroscópio MPU-6050 e acelerômetro: robokitchen. tumblr / post / 68626551378 / imu-gyroscope-and-accelerometer-i-ran-the. Como você já sabe, o acelerômetro ajuda a estabilizar os eixos xey, mas não o eixo z. No entanto, a deriva do eixo z é baixa e continua a ser utilizável para muitas aplicações. Por exemplo, existem vários quadcopters que não usam um magnetômetro e sofrem de z eixo de drift e ainda assim permanecer utilizável. Respondido Dec 16 13 at 14:18 É possível implementar uma média móvel em C sem a necessidade de uma janela de amostras Ive descobri que eu posso otimizar um pouco, escolhendo um tamanho de janela thats um poder de dois para permitir bit-shifting Em vez de dividir, mas não precisava de um buffer seria bom. Existe uma maneira de expressar um novo resultado da média móvel apenas como uma função do antigo resultado e da nova amostra Definir um exemplo de média móvel, através de uma janela de 4 amostras para ser: Adicionar nova amostra e: Uma média móvel pode ser implementada recursivamente , Mas para um cálculo exato da média móvel você deve se lembrar da amostra de entrada mais antiga na soma (ou seja, o a no seu exemplo). Para um comprimento N média móvel você calcula: onde yn é o sinal de saída e xn é o sinal de entrada. Eq. (1) pode ser escrito recursivamente como Então você sempre precisa lembrar a amostra xn-N para calcular (2). Como indicado por Conrad Turner, você pode usar uma janela exponencial (infinitamente longa), que permite calcular a saída somente da saída anterior e da entrada atual: mas esta não é uma média móvel padrão (não ponderada), mas uma média exponencial Ponderada média móvel, onde as amostras mais no passado obter um peso menor, mas (pelo menos em teoria) você nunca esquecer nada (os pesos apenas ficar menor e menor para amostras no passado). Inicialize total 0, count0 (cada vez que vê um novo valor) Então uma entrada (scanf), uma add totalnewValue, um incremento (count), uma divide average (total / count) Esta seria uma média móvel sobre todas as entradas Para calcular a média Sobre apenas as 4 últimas entradas, exigiria 4 variáveis ​​de entrada, talvez copiando cada entrada para uma variável de entrada mais antiga, calculando a nova média móvel como a soma das 4 variáveis ​​de entrada, dividida por 4 (desvio para a direita 2 seria bom se todas as entradas fossem Positivo para fazer o cálculo médio

No comments:

Post a Comment