Criei um pequeno localizador de tocha que usava um ATtiny85 alimentado por uma célula de botão (CR2032). Se parece com isso:
Outro lado:
Atualmente, pesa 5,9 g. O suporte da bateria pesa 1,6 g, assim você pode economizar criando um suporte mais leve (talvez um pouco de plástico para isolamento e soldando diretamente a bateria). O soquete do chip pesa pelo menos 0,5g, para que você também possa economizar soldando os pinos do processador. Então, estamos com 3.8g.
O ATtiny85 possui 512 bytes de EEPROM nos quais você pode usar para registrar leituras. Não tenho certeza de um relógio se você estiver tentando economizar peso, mas se você o iniciar em um horário conhecido, poderá ter uma estimativa razoável do tempo usando a millis()
função para encontrar milissegundos desde a inicialização.
Eu fiz outro há um tempo atrás, que pisca um LED a cada dois segundos:
Isso é parecido. O processador está lá (de cabeça para baixo, embaixo do soquete do chip) e a bateria está embaixo. Isso pesa 6g. A bateria dura alguns anos e isso pisca um LED a cada dois segundos!
Em vez do LED, você poderia ter um termistor para ler a temperatura.
Você pode programá-lo para fazer uma leitura a cada poucas horas e salvá-lo na EEPROM. Então, quando instruído (por exemplo, juntando alguns pinos), ele poderia enviar as leituras para outro pino (via serial).
Você pode economizar mais peso usando dispositivos SMD (montados na superfície) e, talvez, usando uma minúscula placa de circuito que possa ser criada.
Código
O código para o meu localizador de tocha está abaixo. De interesse é o fato de que ele dorme a maior parte do tempo. Também dorme durante a amostragem ADC. Embora no meu caso eu esteja medindo um LDR (resistor dependente da luz), o código para medir um termistor seria semelhante. Você só precisa fazer alguns cálculos no final para transformar a leitura em uma temperatura.
// ATtiny85 torch detector
// Author: Nick Gammon
// Date: 25 February 2015
// ATMEL ATTINY 25/45/85 / ARDUINO
// Pin 1 is /RESET
//
// +-\/-+
// Ain0 (D 5) PB5 1| |8 Vcc
// Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1
// Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1
// GND 4| |5 PB0 (D 0) pwm0
// +----+
/*
Pin 2 (PB3) <-- LDR (GL5539) --> Pin 7 (PB2) <----> 56 k <----> Gnd
Pin 5 (PB0) <---- LED ---> 100 R <-----> Gnd
*/
#include <avr/sleep.h> // Sleep Modes
#include <avr/power.h> // Power management
#include <avr/wdt.h> // Watchdog timer
const byte LED = 0; // pin 5
const byte LDR_ENABLE = 3; // pin 2
const byte LDR_READ = 1; // Ain1 (PB2) pin 7
const int LIGHT_THRESHOLD = 200; // Flash LED when darker than this
// when ADC completed, take an interrupt
EMPTY_INTERRUPT (ADC_vect);
// Take an ADC reading in sleep mode (ADC)
float getReading (byte port)
{
power_adc_enable() ;
ADCSRA = bit (ADEN) | bit (ADIF); // enable ADC, turn off any pending interrupt
// set a2d prescale factor to 128
// 8 MHz / 128 = 62.5 KHz, inside the desired 50-200 KHz range.
ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2);
if (port >= A0)
port -= A0;
#if defined(__AVR_ATtiny85__)
ADMUX = (port & 0x07); // AVcc
#else
ADMUX = bit (REFS0) | (port & 0x07); // AVcc
#endif
noInterrupts ();
set_sleep_mode (SLEEP_MODE_ADC); // sleep during sample
sleep_enable();
// start the conversion
ADCSRA |= bit (ADSC) | bit (ADIE);
interrupts ();
sleep_cpu ();
sleep_disable ();
// reading should be done, but better make sure
// maybe the timer interrupt fired
// ADSC is cleared when the conversion finishes
while (bit_is_set (ADCSRA, ADSC))
{ }
byte low = ADCL;
byte high = ADCH;
ADCSRA = 0; // disable ADC
power_adc_disable();
return (high << 8) | low;
} // end of getReading
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
} // end of WDT_vect
#if defined(__AVR_ATtiny85__)
#define watchdogRegister WDTCR
#else
#define watchdogRegister WDTCSR
#endif
void setup ()
{
wdt_reset();
pinMode (LED, OUTPUT);
pinMode (LDR_ENABLE, OUTPUT);
ADCSRA = 0; // turn off ADC
power_all_disable (); // power off ADC, Timer 0 and 1, serial interface
} // end of setup
void loop ()
{
// power up the LDR, take a reading
digitalWrite (LDR_ENABLE, HIGH);
int value = getReading (LDR_READ);
// power off the LDR
digitalWrite (LDR_ENABLE, LOW);
// if it's dark, flash the LED for 2 mS
if (value < LIGHT_THRESHOLD)
{
power_timer0_enable ();
delay (1); // let timer reach a known point
digitalWrite (LED, HIGH);
delay (2);
digitalWrite (LED, LOW);
power_timer0_disable ();
}
goToSleep ();
} // end of loop
void goToSleep ()
{
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
noInterrupts (); // timed sequence coming up
// pat the dog
wdt_reset();
// clear various "reset" flags
MCUSR = 0;
// allow changes, disable reset, clear existing interrupt
watchdogRegister = bit (WDCE) | bit (WDE) | bit (WDIF);
// set interrupt mode and an interval (WDE must be changed from 1 to 0 here)
watchdogRegister = bit (WDIE) | bit (WDP2) | bit (WDP1) | bit (WDP0); // set WDIE, and 2 seconds delay
sleep_enable (); // ready to sleep
interrupts (); // interrupts are required now
sleep_cpu (); // sleep
sleep_disable (); // precaution
} // end of goToSleep