Skip to topic | Skip to bottom
www.postcogito.org
          ...sine propero notiones
Kiko
Você está aqui: Kiko > PostsEmPortugues > PtBrBlogEntry2008Feb24A Imprimível | fim do tópico


Start of topic | Skip to actions
English Version

Vista frontal do dispositivo quase completo
O dispositivo em ação, mostrando voltagem e
freqüência da linha elétrica, mas ainda nenhum
evento.
O dispositivo quase completo, visto de cima
O hardware visto de cima, quase completo: já
temos a EEPROM TWI, LCD, baterias e o buzzer.

Progresso com o Monitorador de Falhas de Energia

Rec 24-fev-2008 21:31

Na etapa anterior fiquei surpreso que as coisas funcionaram bem logo de primeira. Dessa vez eu tropecei em algumas armadilhas menores mas irritantes.

Para por o LCD para funcionar, adaptei um conjunto antigo de rotinas de LCD de um projeto anterior para que elas não precisassem usar o sinal RW. Ajustando apropriadamente atrasos, rapidamente obtive sucesso. Então reestruturei as rotinas de sorte que uma sub-tarefa do laço principal se encarregasse de mover os bytes de um buffer para o LCD, de sorte que imprimir coisas se torne tão simples quanto jogar os dados nesse buffer -- a vantagem é que podemos imprimir tão rápido quanto possível sem nos preocuparmos com a temporização.

Também fiquei satisfeito com o fato que o módulo de LCD consumia meros 0,8mA, contribuindo muito pouco para o consumo total do dispositivo, de apenas 8mA (ou seja: ainda estamos abaixo dos 10mA projetados).

Mas logo após eu adicionar o LCD, a primeira armadilha se apresentou: as medidas de freqüência, outrora impecáveis, começaram a exibir uma variações esporádicas: uma hora ficava em 60.000Hz, no instante seguinte pulava para 63Hz, depois um número bem baixo, depois de volta ao normal. Eu tinha adicionado acumuladores para contar quantos semiciclos "rápidos" ou "lentos" haviam ocorrido (isto é, semiciclos com períodos fora de +/- 10% das 1.042 contagens esperadas do Timer1) e notei que o contador de "semiciclos rápidos" sempre incrementava quanto essas anomalias aconteciam.

Confiante demais que eu estava com os resultados anteriores, quase descartei o probelma como sendo alguma esquisitice da minha rede elétrica, tal como a onda senoidal achatada. Então piorou, depois melhorou e eu fiquei muito confuso. Então pensei que poderia ser um problema de software e logo descobri que ele desaparecia se eu desabilitasse o código do LCD.

Algumas horas de frustrante depuração me levaram a uma instrução assembly em particular: aquela que movia os 4 bits inferiores para o LCD para o barramento de dados do LCD. Então caiu a ficha: a linha D7 do LCD está ligada ao pino exatamente ao lado do pino ICP, de sorte que meu problema era ruído de chaveamento elétrico: toda vez que o caractere que estava sendo enviado para o LCD tinha o bit 3 ligado e o pino ICP estava em zero, ele disparava o detector de transição de nível do sistema de captura de eventos. Aparentemente, esse circuito é sensível demais.

Em retrospectiva, talvez a coisa certa a fazer tivesse sido mover o barramento de dados do LCD todo para outros pinos, digamos, para os pinos da porta SPI que estão em grande medida sem uso (eu os tinha deixado intencionalmente sem uso para que pudéssemos usá-los para a programação "in-system" e para uma futura expansão para usar cartões SD como armazenamento). Mas eu estava cansado e sem paciência para um longo trabalho de resoldagem, então eu simplesmente movi a linha D7 para o pino PD2/INT0 -- o que fez a manipulação de bits nas rotinas de LCD um pouco feiosas e arruinou um plano que eu vinha cogitando de usar o INT0 como uma segunda porta serial para obter medidas do meu multímetro digital ET-2210 e adicionar um sistema de auto-calibração bem preciso.

De qualquer forma, após esse conserto gambiarresco, tudo funcionou perfeitamente. Preciso me lembrar disso tudo ao projetar a placa de circuito impresso.

Também adicionei o 24C512, uma memória EEPROM TWI de 512 kibibits (64KiB x 8bits). O barramento TWI requer resistores de pull-up, mas eu nem me dei ao trabalho de adicioná-los porque podemos usar os pull-ups embutidos nos pinos do AVR, bastando para isso ativá-los por software.

Enquanto eu estava no ciclo de desenvolvimento (codificação-upload-teste) da rotina de tratamento da interrupção da porta TWI, percebi um problema de temporização em potencial: as escritas de bytes para a EEPROM podem demorar até 10ms para serem completadas, de sorte que escrever 32 bytes (o tamanho da estrutura de dados que representa um evento) pode levar mais de 320ms ou quase 40 semiciclos Isso significa que se tivermos dois eventos acontecendo em menos de 40 semiciclos de distância um do outro, poderemos não ser capazes de registrá-los.

Relendo o datasheet da 24C512, achei uma solução fácil: o chip é capaz de receber uma página completa de 128 bytes de uma só vez, em uma única transação do barramento TWI e salvar a página completa em um único período de 10ms. Por isso, reescrevi as rotinas de armazenamento de eventos da seguinte forma: criei uma fila capaz de armazenar até 8 eventos (256 bytes) em RAM. Toda vez que acumulamos 4 eventos (exatamente uma página de 128 bytes), o sistema joga os dados para a EEPROM TWI, liberando em seguida o espaço na fila. Rereading the 24C512 datasheet I found an easy solution: the chip is capable

Quatro eventos requerem no mínimo 8 semiciclos (um início e um final em diferentes semiciclos, vezes quatro), mas com esse esquema de escrita por página, podemos descarregar 4 eventos pendentes para a EEPROM em menos de 15ms (os 10ms da escrita na EEPROM mais o tempo de transmissão dos bytes no barramento), ou apenas dois semiciclos. Em outras palavras, podemos armazenar eventos quatro vezes mais rápido do que eles são gerados, o que nos permite arcar com trens de eventos bem rápidos. Os 128 bytes excedentes na fila se encarregam de segurar as pontas mesmo que a EEPROM esteja ocupada salvando uma página ou recuperando dados.

Isso também significa que deve ser seguro usar um chip com tamanho de página menor desde que a taxa de armazenamento versus de geração de eventos seja maior que 1. Uma 24C256 (32KiB x 8), com páginas de 64 bytes, deve ser usável, com uma razão de 2 para 1. Já uma 24C128 (16KiB x 8), com páginas de 32 bytes, dá uma razão de apenas um pouco mais que um pra um, deixando-nos com uma temporização desconfortavelmente crítica mas talvez factível (EEPROMs mais novas têm tempos de escrita menores, às vezes tão baixos quanto 5ms). Mas o mesmo argumento diz que EEPROMs de 64 kibibits ou menores provavelmente nos darão problemas.

Eis aqui a versão 0.4 do firmware com os seguintes recursos adicionais:

  • Suporte a LCDs compatíveis com HD44780 em modo de 4 bits
    • Atente para a mudança na atribuicão dos pinos: D7 agora está no PD2 -- veja discussão acima;
  • Rotinas de suporte a leitura/escrita de bytes/páginas na EEPROM I2C/TWI baseada em interrupções;
  • Registra eventos de queda de energia;
  • Opcionalmente registra subtensão e sobretensão;
  • Opcionalmente registra desvios muito grandes em relação à freqüência esperada de 60Hz
  • Apita quando a energia cai ou volta; emite cliques quando há sobretensão/subtensão ou variação excessiva de freqüência;
  • Permite consultar eventos anteriores armazenados na EEPROM

Novos comandos:

  • event: sem argumentos, diz quantos eventos temos armazenados; com um argumento numérico, imprime detalhes daquele evento;
  • clear: apaga dos os eventos armazenados (zera os contadores, de sorte que os novos dados sobrescrevem os anteriores)
  • param: com um argumento, mostra o valor daquele parametro; com dois argumentos, define seu valor;

Esses comandos foram usados durante desenvolvimento/depuração e só estarão disponíveis se a macro HAVE_XTRA_CMDS for definida:

  • start: artificialmente inicia um evento: dá partida no contador de tempo decorrido e a data/hora atual do relógio de tempo real é copiada para a data inical do evento. O argumento é o tipo do evento;
  • finish: artificialmente termina um evento, descarregando-os para a EEPROM quando uma página é completada;
  • poke: escreve um byte na EEPROM no endereço especificado;
  • fill: prenche uma página da EEPROM com uma seqüência de bytes
  • dump: imprime o conteúdo de uma região da EEPROM em hexa.

Algumas variáveis globais podem ser mudadas pelo comando params:

  • 0: Bit mapped flags:
  • 0: Bits contendo alguns flags:
    • 1: Variações de freqüência também geram eventos;
    • 2: Subtensão/sobretensão também geram eventos;
  • 1: Valor mínimo cru do ADC para detecção de queda de energia: se menor que esse valor, inicia um novo evento de falha de energia. Se mais que isso, termina o evento atual, se havia algum;
  • 2: Valor mínimo cru do ADC para detecção de subtensão: se menor que isso mas maior que o valor do parâmetro 1, incrementa o contador de "semiciclos em subtensão";
  • 3: Valor máximo cru do ADC para detecção de sobretensão: se maior que isso, incrementa o contador de "semiciclos em sobretensão";
  • 4: Valor mínimo cru do ICR: se menor que isso, incrementa o contador de "semiciclos em alta freqüência";
  • 5: Valor máximo cru do ICR: se maior que isso, incrementa o contador de "semiciclos em baixa freqüência";
  • 6: Bipa por essa quantidade de milissegundos quando a energia cai;
  • 7: Bipa por essa quantidade de milissegundos quando a energia volta;
  • 8: Bipa por essa quantidade de milissegundos quando há subtensão;
  • 9: Bipa por essa quantidade de milissegundos quando há sobretensão;
  • 10: Bipa por essa quantidade de milissegundos quando há baixa de freqüência;
  • 11: Bipa por essa quantidade de milissegundos quando há freqüência muito alta;

O sistema de geração de eventos está funcionando bem para o caso de quedas de energia, mas não estou satisfeito com os registros de variações de freqüência/sobrevoltage/subvoltagem. Por ser apenas um simples detector de transições, ruído na linha às vezes gera dúzias de eventos. Planejo melhorar isso na próxima versão.

Há várias outros recursos que ainda precisam ser implementados: monitoração do estado da bateria, por exemplo. Mas, no geral, as coisas estão funcionando e estou razoavelmente feliz com os resultados. O tamanho do código está um pouco maior do que eu esperava: com 6.496 bytes, já vamos em 82% do tamanho disponível (8KiB - 256 bytes para o bootloader). O código certamente pede uma refatoração e melhor modularização. Vou deixar o dispositivo rodando por algumas semanas para ver que tipos de eventos pego e o quão satisfeito fico.
topo


Você está aqui: Kiko > PostsEmPortugues > PtBrBlogEntry2008Feb24A

topo

Creative Commons License   O conteúdo deste site está disponibilizado nos termos de uma Licença Creative Commons, exceto onde dito em contrário.
  The content of this site is made available under the terms of a Creative Commons License, except where otherwise noted.