Eu investiguei as opções de sono do ATmega328 e li alguns artigos sobre ele, e gostaria de entender se há mais opções.
Então, eu gostaria de obter a menor corrente possível, para que nada menos que 100uA fosse bom - desde que eu possa ouvir uart e interromper para acordar.
Estou usando um PCB personalizado (não o UNO), com ATmega328p.
Configurando o chip para dormir profundamente:
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu ();
não iria acordar com comunicação serial, de acordo com isso .
Você precisará colocá-lo no IDLE
modo, para ouvir serial, mas isso consumiria alguns mA -bad.
Eu encontrei este link onde você pode conectar no hardware o serial à interrupção - o que é perigoso para que você possa perder dados e, além disso, preciso desses 2 pinos de interrupção.
Também li este artigo da Gammon , onde é possível desativar algumas coisas, para que você possa dormir inativo com muito menos energia - mas ele não mencionou exatamente como você obtém isso:
power_adc_disable();
power_spi_disable();
power_timer0_disable();
power_timer1_disable();
power_timer2_disable();
power_twi_disable();
Então, basicamente, existe alguma opção lá fora, para obter menos de 0,25mA, pelo menos, e também ouvir porta serial, sem qualquer manipulação de hardware? Por exemplo, acordando com entrada longa de dados seriais ?
Respostas:
Um quadro que fazemos faz isso.
Em suspensão, a interrupção de baixo nível INT0 está ativada
A rotina de serviço de interrupção INT0 define um sinalizador e desativa a interrupção
Ao acordar, verificamos a bandeira (existem outras fontes de interrupção)
No lado das comunicações, usamos um protocolo de mensagens que possui um caractere inicial
>
e um final\r
. por exemplo>setrtc,2015,07,05,20,58,09\r
. Isso fornece alguma proteção básica contra a perda de mensagens, pois os caracteres recebidos não são processados até que um>
seja recebido. Para ativar o dispositivo, enviamos uma mensagem fictícia antes da transmissão. Um único personagem faria isso, mas enviamos>wakeup\r
hehe.O dispositivo permanece acordado por 30 segundos após o recebimento da última mensagem no caso de novas mensagens. Se uma nova mensagem for recebida, o cronômetro de 30 segundos será redefinido. O software da interface do PC envia uma mensagem fictícia a cada segundo para manter o dispositivo acordado enquanto o usuário o conecta para configuração, etc.
Este método não oferece absolutamente nenhum problema. A placa com alguns periféricos usa cerca de 40uA ao dormir. A corrente real consumida pelo ATMega328P provavelmente está em torno de 4uA.
Atualizar
Na olhada na folha de dados, mostra que o pino RX também é o pino 16 de interrupção de troca de pinos (PCINT16)
Assim, outro método sem fios pode ser
Antes de dormir: Defina o bit da máscara de interrupção de mudança de porta no PCMSK2 para PCINT16, limpe o sinalizador da porta de troca de pinos 2 no PCIFR, ative a interrupção da porta de troca de pinos 2 (PCINT16-PCINT23) configurando PCIE2 em PCICR.
Configure um ISR para a interrupção da porta 2 de troca de pinos e continue como antes.
A única ressalva com a interrupção de mudança de porta é que a interrupção é compartilhada entre todos os 8 pinos que estão habilitados para essa porta. Portanto, se você tiver mais de uma alteração de pinos ativada para a porta, precisará determinar qual acionou a interrupção no ISR. Isso não é um problema se você não estiver usando nenhuma outra interrupção de troca de pinos nessa porta (neste caso, PCINT16-PCINT23)
Idealmente, é assim que eu teria projetado nossa prancha, mas o que temos funciona.
fonte
O código abaixo alcança o que você está perguntando:
Usei uma interrupção de troca de pinos no pino Rx para perceber quando os dados seriais chegam. Neste teste, a placa entra em suspensão se não houver atividade após 5 segundos (o LED "acordado" se apaga). Os dados seriais recebidos fazem com que a interrupção da troca de pinos ative a placa. Ele procura um número e pisca o LED "verde" esse número de vezes.
Corrente medida
Correndo a 5 V, medi cerca de 120 nA de corrente quando estava dormindo (0,120 µA).
Mensagem de despertar
Um problema, no entanto, é que o primeiro byte que chega é perdido devido ao fato de o hardware serial esperar um nível decrescente no Rx (o bit de inicialização) que já chegou no momento em que está totalmente acordado.
Sugiro (como na resposta da geometrikal) que você primeiro envie uma mensagem "acordada" e faça uma pausa por um curto período de tempo. A pausa é garantir que o hardware não interprete o próximo byte como parte da mensagem de ativação. Depois disso, deve funcionar bem.
Como isso usa uma interrupção de troca de pinos, nenhum outro hardware é necessário.
Versão alterada usando SoftwareSerial
A versão abaixo processa com êxito o primeiro byte recebido em série. Faz isso da seguinte maneira:
Usando SoftwareSerial, que usa interrupções de alteração de pinos. A interrupção causada pelo bit inicial do primeiro byte serial também ativa o processador.
Configurando os fusíveis para que possamos usar:
Inspirado pelo FarO em um comentário, isso permite que o processador seja ativado em 6 ciclos de clock (750 ns). A 9600 bauds, cada vez que o bit é 1/9600 (104,2 µs), portanto o atraso extra é insignificante.
O consumo de energia durante o sono foi medido em 260 nA (0,260 µA), de modo que o consumo é muito baixo quando não é necessário.
Observe que, com os fusíveis configurados assim, o processador funciona a 8 MHz. Portanto, você precisa informar o IDE sobre isso (por exemplo, selecione "Lilypad" como o tipo de placa). Dessa forma, os atrasos e o SoftwareSerial funcionarão na velocidade correta.
fonte