버튼 셀 (CR2032)로 구동되는 ATtiny85를 사용한 작은 토치 로케이터 를 구성했습니다 . 다음과 같이 보입니다 :
다른 쪽:
현재 무게는 5.9g입니다. 배터리 홀더의 무게는 1.6g이므로 더 가벼운 홀더 (아마도 절연 용 플라스틱 조각을 만들고 배터리에 직접 납땜)를 사용하여 절약 할 수 있습니다. 칩 소켓의 무게는 최소 0.5g이므로 프로세서 핀에 납땜하면 칩 소켓을 절약 할 수 있습니다. 그래서 우리는 3.8g으로 떨어졌습니다.
ATtiny85는 512 바이트의 EEPROM을 가지고 있으며,이를 통해 기록을 기록 할 수 있습니다. 체중을 줄이려고하면 시계에 대해 잘 모르겠지만 알려진 시간에 시작하면 시작 millis()
이후 밀리 초를 찾는 기능을 사용하여 합리적인 시간을 추정 할 수 있습니다 .
나는 몇 초 전에 또 다른 것을 만들었습니다 .2 초마다 LED가 깜박입니다.
비슷합니다. 프로세서는 칩 소켓 아래에 거꾸로 있고 배터리는 아래에 있습니다. 무게는 6g입니다. 배터리는 몇 년 동안 지속되었으며 몇 초마다 LED가 깜박입니다!
LED 대신 서미스터가 온도를 읽을 수 있습니다.
몇 시간마다 읽도록하고 EEPROM에 저장하도록 프로그래밍 할 수 있습니다. 그런 다음 지시를 받으면 (예 : 몇 개의 핀을 결합하여) 판독 값을 다른 핀 (직렬을 통해)으로 출력 할 수 있습니다.
SMD (표면 장착) 장치를 사용하고 구성 할 수있는 작은 회로 기판을 사용하여 더 많은 무게를 절약 할 수 있습니다.
암호
내 토치 로케이터의 코드는 다음과 같습니다. 중요한 것은 그것이 대부분의 시간 동안 잠 들어 있다는 사실입니다. 또한 ADC 샘플링 중에는 휴면 상태입니다. 필자의 경우 LDR (광 의존 저항)을 측정하고 있지만 서미스터 측정 코드는 비슷합니다. 측정 값을 온도로 바꾸려면 마지막에 약간의 계산 만하면됩니다.
// 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