Ich habe mir einen kleinen Taschenlampensucher ausgedacht, der einen ATtiny85 verwendet, der von einer Knopfzelle (CR2032) gespeist wird. Es sieht aus wie das:
Andere Seite:
Das wiegt derzeit 5,9 g. Der Batteriehalter wiegt 1,6 g, sodass Sie dies sparen können, indem Sie einen leichteren Halter herstellen (möglicherweise etwas Plastik zur Isolierung und direktes Löten an die Batterie). Der Chip-Sockel wiegt mindestens 0,5 g, sodass Sie dies auch durch Löten an den Prozessorstiften sparen können. Wir sind also auf 3,8 g gesunken.
Der ATtiny85 verfügt über 512 Byte EEPROM, in dem Sie Messwerte protokollieren können. Ich bin mir bei einer Uhr nicht sicher, ob Sie versuchen, Gewicht zu sparen, aber wenn Sie sie zu einem bekannten Zeitpunkt starten, können Sie eine vernünftige Schätzung der Zeit erhalten, indem Sie die millis()
Funktion verwenden, um Millisekunden seit dem Start zu ermitteln.
Ich habe vor einiger Zeit eine neue gemacht, die alle paar Sekunden eine LED blinkt:
Das ist ähnlich. Der Prozessor befindet sich dort (verkehrt herum unter dem Chip-Sockel) und der Akku befindet sich darunter. Das wiegt 6g. Die Batterie hat ein paar Jahre gedauert und alle paar Sekunden blinkt eine LED!
Anstelle der LED können Sie auch einen Thermistor zum Ablesen der Temperatur verwenden.
Sie können es so programmieren, dass es alle paar Stunden eine Lesung durchführt und im EEPROM speichert. Wenn es angewiesen wird (z. B. durch Verbinden einiger Stifte), kann es die Messwerte an einen anderen Stift ausgeben (über seriell).
Sie könnten mehr Gewicht sparen, indem Sie SMD-Geräte (Surface Mounted) verwenden und möglicherweise eine winzige Leiterplatte verwenden, die Sie herstellen könnten.
Code
Der Code für meinen Taschenlampensucher ist unten. Interessant ist die Tatsache, dass es die meiste Zeit schläft. Es schläft auch während der ADC-Abtastung. Obwohl ich in meinem Fall einen LDR (lichtabhängigen Widerstand) messe, wäre der Code zum Messen eines Thermistors ähnlich. Sie müssen am Ende nur einige Berechnungen durchführen, um den Messwert in eine Temperatur umzuwandeln.
// 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