Creé un pequeño localizador de antorchas que usaba un ATtiny85 alimentado por una celda de botón (CR2032). Se parece a esto:
Otro lado:
Que actualmente pesa 5,9 g. El soporte de la batería pesa 1,6 g, por lo que podría ahorrarlo haciendo un soporte más liviano (tal vez un poco de plástico para aislar y soldar directamente a la batería). El zócalo del chip pesa al menos 0,5 g, por lo que también puede guardarlo soldando a los pines del procesador. Así que hemos bajado a 3.8g.
El ATtiny85 tiene 512 bytes de EEPROM que puede usar para registrar lecturas. No estoy seguro acerca de un reloj si está tratando de ahorrar peso, pero si lo inicia a una hora conocida, podría tener una estimación razonable del tiempo utilizando la millis()
función para encontrar milisegundos desde el inicio.
Hice otro hace un tiempo que parpadea un LED cada dos segundos:
Eso es similar El procesador está allí (boca abajo debajo del zócalo del chip) y la batería está debajo. Eso pesa 6 g. ¡La batería ha durado un par de años, y eso parpadea un LED cada dos segundos!
En lugar del LED, podría tener un termistor para leer la temperatura.
Puede programarlo para tomar una lectura cada pocas horas y guardarlo en EEPROM. Luego, cuando se le indique (por ejemplo, uniendo un par de pines), podría enviar las lecturas a otro pin (a través de serie).
Podría ahorrar más peso usando dispositivos SMD (montados en la superficie), y quizás usando una pequeña placa de circuito que podría inventar.
Código
El código para mi localizador de antorchas está abajo. Es interesante el hecho de que duerme la mayor parte del tiempo. También duerme durante el muestreo de ADC. Aunque en mi caso estoy midiendo un LDR (resistencia dependiente de la luz), el código para medir un termistor sería similar. Solo necesita hacer algunos cálculos al final para convertir la lectura en 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