Atualmente, estou desenvolvendo um sistema LCD gráfico para exibir temperaturas, fluxos, tensões, potência e energia em um sistema de bomba de calor. O uso de um LCD gráfico significa que metade da minha SRAM e ~ 75% do meu flash foram usadas por um buffer de tela e seqüências de caracteres.
Atualmente, estou exibindo valores mínimo / máximo / médio para energia À meia-noite, quando o valor diário é redefinido, o sistema verifica se o consumo do dia está acima ou abaixo do mínimo ou máximo anterior e armazena o valor. A média é calculada dividindo o consumo acumulado de energia pelo número de dias.
Gostaria de exibir a média diária da última semana e mês (4 semanas por simplicidade), ou seja, uma média móvel. Atualmente, isso envolve a manutenção de uma matriz de valores nos últimos 28 dias e o cálculo da média de toda a matriz nos meses mensais e nos últimos 7 dias na semana.
Inicialmente, eu fazia isso usando uma matriz de flutuadores (como a energia está na forma "12,12kWh"), mas isso estava usando 28 * 4 bytes = 112 bytes (5,4% da SRAM). Não me importo de ter apenas um único ponto decimal de resolução, então mudei para usar uint16_t e multiplique o número por 100. Isso significa que 12.12 é representado como 1212 e divido por 100 para fins de exibição.
O tamanho da matriz agora está reduzido a 56 bytes (muito melhor!).
Não há uma maneira trivial de reduzir a figura para um uint8_t que eu possa ver. Eu pude tolerar a perda de uma casa decimal ("12,1 kWh" em vez de "12,12 kWh"), mas o consumo geralmente é superior a 25,5 kWh (255 é o valor mais alto representado por um número inteiro não assinado de 8 bits). O consumo nunca ficou abaixo de 10,0kWh ou acima de 35,0kWh, então é possível subtrair 10 dos números armazenados, mas sei que um dia excederemos esses limites.
Testei o código para compactar valores de 9 bits em uma matriz. Isso fornece um intervalo de 0 a 51,2 kWh e usa 32 bytes no total. No entanto, acessar uma matriz como essa é muito lento, especialmente quando você precisa iterar sobre todos os valores para calcular uma média.
Então, minha pergunta é: existe uma maneira mais eficiente de calcular uma média móvel com três janelas - vida útil, 28 dias e 7 dias? Eficiência significa menor em termos de uso de SRAM, mas sem a penalidade de um grande código. Posso evitar armazenar todos os valores?
fonte
Respostas:
Se seus dados tiverem um desvio padrão baixo, um método seria somar valores pela janela e continuar subtraindo a média da soma, enquanto adicionava o novo valor.
Isso funcionaria bem se não houvesse discrepâncias , levando ao erro agregado tendendo a zero ao longo do tempo.
fonte
você pode usar um método diferente, mantém a média atual e depois
não é uma verdadeira média móvel e possui semântica diferente, mas pode atender às suas necessidades
para um método de cálculo mais eficiente para sua solução de 9 bits por valor, você pode manter os 8 bits mais altos em uma matriz e separar os bits menos significativos:
para definir um valor, você precisa dividi-lo
resultando em 2 turnos um AND e um OR e um não
Para calcular a média, você pode usar vários truques de bits para acelerar:
você pode usar um contador de bits paralelo eficiente para o
bitcount()
fonte
Que tal armazenar apenas a diferença do valor anterior? Em eletrônica, existe um conceito semelhante chamado conversor Delta Sigma, usado para conversores DA / AD. Ele se baseia no fato de que a medição anterior está razoavelmente próxima da atual.
fonte
Por que você não pode simplesmente adicionar os valores assim que obtê-los? Então, o que quero dizer é que você obtém o valor do dia 1, divide-o por 1 e armazena-o e o 1 em algum lugar. Em seguida, multiplique o 1 pelo valor e adicione-o ao próximo valor e divida os dois por 2.
Fazer esse método criaria uma média móvel com duas ou três variáveis, como posso pensar. Eu escreveria algum código, mas sou novo no stackexchange, portanto, tenha paciência comigo.
fonte
Você pode se aproximar o suficiente armazenando 11 valores em vez de 28, talvez algo como:
Em outras palavras, em vez de armazenar todos os detalhes de todos os dias nos últimos 27 dias, (a) armazene aproximadamente 7 valores de informações diárias detalhadas dos últimos 7 dias, e também (b) armazene 4 ou mais "resumidos" valores da informação total ou média de cada uma das últimas quatro semanas.
fonte