我爱制作网

 找回密码
 注册已关闭

QQ登录

只需一步,快速开始

DIY电子蜡烛

本文地址:http://www.xjbjf.com/article-2002-1.html
文章摘要:DIY电子蜡烛,具有国际目兔顾犬学农,好好笑朝前夕惕竹木制品。

2017-1-20 17:09| 发布者: 365外围投注| 查看: 2470| 评论: 0|原作者: 转载

摘要: 想想当你好不容易跟女朋友共度烛光晚餐,却因为蜡烛点没了或打翻着火了,那是一件多么坑爹的事啊!今天为你分享一款自己diy的超自然的烛光蜡烛。 ATtiny 电子蜡烛,皮特•米尔斯开发这个伟大的蜡烛,正 ...
      想想当你好不容易跟女朋友共度烛光晚餐,却因为蜡烛点没了或打翻着火了,那是一件多么坑爹的事啊!今天为你分享一款自己diy的超自然的烛光蜡烛。
1.jpg

      ATtiny 电子蜡烛,皮特•米尔斯开发这个伟大的蜡烛,正如我们图片所见到的一样,但怎样让这蜡烛的光芒像传统的蜡烛一样闪烁呢。
2.jpg

      皮特使用一个高亮的LED和一些模拟的辅助软件,365外围投注:这样就使得ATtiny 电子蜡烛的烛光和传统蜡烛拥有一样的闪烁的烛光,并且优于传统蜡烛,因为它不伴有明火的危险。
3.jpg

      ATtiny 电子蜡烛最难的部分就闪烁神态逼真,所以皮特做了一个蜡烛光检测电阻( LDR )和固定电阻作为一个分压器。这是作为ATTINY85 ADC之中的一个输入端,并离散时间间隔的进行采样。采样速率为100毫秒。然后将采集的8bit的电频值存储到EEPROM中,以便记录蜡烛的闪烁图谱,驱动将其连接的LED、PWM形成通路。在用三节干电池供电。最后您只需编程程序,然后通过开关进行控制。
4.jpg

通过视频来看看效果:


下面是ATtiny 电子蜡烛的电路图
5.jpg

下面是程序的代码以及写入EEPROM的数据

程序代码
view plainprint?
/*
Program Description: This program reads a light detecting resistor thru an internal ADC and stores the value,
after scaling it, to eeprom.  This ADC value is sent to a PWM channel with attached led.  This is essentially a data logger
for light and replay by LED.  If, if you aim the LDR at a flickering candle during its recording phase, you have a flickering
led candle.  

A circuit description and other details can be found at http://www.xjbjf.com/534

Filename: ATTiny_Candle_v1.0.c
Author: Pete Mills

Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms

*/



//********** Includes **********

#include      
#include     
#include  




//********** Definitions **********

// LED for flame simulation

#define LED   PB0   
#define LED_PORT PORTB
#define LED_DDR  DDRB



// Light Detecting Resistor for recording a live flame

#define LDR   PINB3  
#define LDR_PORT PINB
#define LDR_DDR  DDRB



// Tactile Switch Input

#define SW1   PINB4
#define SW1_PORT PINB
#define SW1_DDR  DDRB


#define ARRAY_SIZE 500  // size of the flicker array
#define SAMPLE_RATE 100  // ms delay for collecting and reproducing the flicker



//********** Function Prototypes **********

void setup(void);
void toggle_led(void);
void program_flicker(void);
void led_alert(void);
void eeprom_save_array(void);
void eeprom_read_array(void);
void scale_array(void);
uint8_t get_adc(void);
uint8_t scale( uint8_t input, uint8_t inp_low, uint8_t inp_hi, uint8_t outp_low, uint8_t outp_hi);
uint8_t is_input_low(char port, char channel, uint8_t debounce_time, int input_block);




//********** Global Variables **********

uint8_t flicker_array[ ARRAY_SIZE ] = { 0 };
uint8_t EEMEM ee_flicker_array[ ARRAY_SIZE ] = { 0 };


int main(void)
{

uint16_t replay = 0;

setup();

eeprom_read_array();



while(1)
{  
  
   
   
   
  if( is_input_low( SW1_PORT, SW1, 25, 250 ) )
  {
   
   // program the flicker
   // after entering and upon completion, a predetermined flash pattern will occur as described in led_alert()   
   // aim the ldr at a flickering candle or any other light source ( like a laser ) you want to record during this time
   // and upon completion the values are stored to eeprom.  They are played back immediately as well  
   // as being recalled from eeprom upon first start up
   
   led_alert();
   program_flicker();
   scale_array();
   eeprom_save_array();
   led_alert();
  }
   
   
   
  // replay the recorded flicker pattern  
   
  OCR0A = flicker_array[ replay ];
  ++replay;
   
  if( replay >= ( ARRAY_SIZE - 13 ) ) // if the end of the stored array has been reached
  {  
   replay = 0;          // start again from the beginning
   //led_alert();
  }
   
  _delay_ms( SAMPLE_RATE );
  _delay_ms( 3 );    // ADC Conversion time
   
}
}




//********** Functions **********

void setup(void)
{



//********* Port Config *********

LED_DDR |= ( 1 << LED);   // set PB0 to "1" for output  
LED_PORT &= ~( 1 << LED );   // turn the led off

LDR_DDR &= ~( 1 << LDR );   // set LDR pin to 0 for input
LDR_PORT |= ( 1 << LDR );   // write 1 to enable internal pullup

SW1_DDR &= ~( 1 << SW1 );   // set sw1 pin to 0 for input
SW1_PORT |= ( 1 << SW1 );   // write a 1 to sw1 to enable the internal pullup



//********** PWM Config *********
  
TCCR0A |= ( ( 1 << COM0A1 ) | ( 1 << WGM01 ) | ( 1 << WGM00 ) ); // non inverting fast pwm
TCCR0B |= ( 1 << CS00 ); // start the timer
  
  
  
//********** ADC Config **********
  
ADMUX |= ( ( 1 << ADLAR ) | ( 1 << MUX1 ) | ( 1 << MUX0 ) );  // left adjust and select ADC3
ADCSRA |= ( ( 1 << ADEN ) | ( 1 << ADPS2 ) | ( 1 << ADPS1 ) ); // ADC enable and clock divide 8MHz by 64 for 125khz sample rate
DIDR0 |= ( 1 << ADC3D ); // disable digital input on analog input channel to conserve power

}




void toggle_led()
{
    LED_PORT ^= ( 1 << LED );
}




uint8_t is_input_low( char port, char channel, uint8_t debounce_time, int input_block )
{

/*
This function is for debouncing a switch input
Debounce time is a blocking interval to wait until the input is tested again.
If the input tests low again, a delay equal to input_block is executed and the function returns ( 1 )
*/
         
if ( bit_is_clear( port, channel ) )
{
  _delay_ms( debounce_time );
   
   if ( bit_is_clear( port, channel ) )  
   {
    _delay_ms( input_block );
    return 1;
   }
  
}

return 0;
}




uint8_t get_adc()
{
ADCSRA |= ( 1 << ADSC );   // start the ADC Conversion
  
while( ADCSRA & ( 1 << ADSC ));  // wait for the conversion to be complete
  
return ~ADCH; // return the inverted 8-bit left adjusted adc val

}




void program_flicker()
{  
// build the flicker array
  
for( int i = 0; i < ARRAY_SIZE; i++ )
{
  flicker_array[ i ] = get_adc();   
  _delay_ms( SAMPLE_RATE );
}

}




void led_alert()
{
// this is a function to create a visual alert that an event has occured within the program
// it toggles the led 10 times.
  
for( int i = 0; i < 10; i++ )
{
  OCR0A = 0;
  _delay_ms( 40 );
  OCR0A = 255;
  _delay_ms( 40 );
}

}




void eeprom_save_array()
{  
for( int i = 0; i < ARRAY_SIZE; i++ )
{
  eeprom_write_byte( &ee_flicker_array[ i ], flicker_array[ i ] );
   
}
}




void eeprom_read_array()
{
for( int i = 0; i < ARRAY_SIZE; i++ )
{
  flicker_array[ i ] = eeprom_read_byte( &ee_flicker_array[ i ] );
   
}
}




uint8_t scale( uint8_t input, uint8_t inp_low, uint8_t inp_hi, uint8_t outp_low, uint8_t outp_hi)
{
return ( ( ( input - inp_low ) * ( outp_hi - outp_low ) ) / ( ( inp_hi - inp_low ) + outp_low ) );
}




void scale_array()
{
uint8_t arr_min = 255;
uint8_t arr_max = 0;
uint8_t out_low = 20;
uint8_t out_high = 255;
  
  
  
// find the min and max values
  
for( int i = 0; i < ARRAY_SIZE; i++ )
{
  if( flicker_array[ i ] < arr_min )
   arr_min = flicker_array[ i ];
   
  if( flicker_array[ i ] > arr_max )
   arr_max = flicker_array[ i ];
}
  
  
  
// now that we know the range, scale it
  
for( int i = 0; i < ARRAY_SIZE; i++ )
{
  flicker_array[ i ] = scale( flicker_array[ i ], arr_min, arr_max, out_low, out_high );
}
  
}   igh );
}
  
}   igh );
}
  
}   
}
  
}   
}
  
}   
}
  
}    }
  
}    }
  
}    }
  
}                                 




EEPROM数据

:10000000777B7D7B78BA95535E3E3E4352353E7595 :100010004B657B5263586B5562777287858C5D7A2E :10002000535D5062556F6758784E55956B6D7D7373 :100030007D5B6B686A6A606B7777987A87605B6BC9 :10004000534A5368453B65679C6067537375638A81 :100050007F8388806358586B7A787B838A878A8508 :1000600083888A8A8A8A8A8C8A8A8A8A8A88837F0B :100070007D7B7A78777570707270704D416D6860B5 :1000800035353D3B4145525E41535D60656A5048A0 :100090004B4E3535313333363B40504E525D605315 :1000A000564B352D2E2E353838393B383158406077 :1000B0004D505A5D434053585A554E31312B2E33D3 :1000C0003136353638393938404A413B506240364E :1000D000292D455E5D523E333B433545383531333E :1000E00036363936383B4136363039332B29335A98 :1000F0006356413D5052556065553B302E303B4E66 :10010000362E2B3B393D4A503D45584E4B4E4A45C5 :10011000584B555D5B56585E60775E385A52464B79 :10012000504A4A354E412E363638524B463B3340C4 :100130004E605A504D434A504B48403D4046525BFA :100140006263635B52465B43554526353B5B434DDB :100150004056585A5D50464545413B437287908A08 :100160008F979D9573656B4D464555554156555531 :10017000565A5A5B5E56625565585A62686D6D6B89 :10018000686A6F656D316F55485055675A41555EC5 :100190006065686863606A60676A7F838C8788923D :1001A0008D8F888C8C85826A4E35231119433B4193 :1001B000674A4A3B2E3045414A5848705B6D72622F :1001C0007567565A5E554D77532D36415D55404003 :1001D0004040403E415E82928888909488857B634F :1001E000555356555053550334013A7EFF01603E36 :1001F0003E28018EFFFFFFFFFFFFFFFFFFFFFFFF16 :00000001FF FFFFFFFFFFFFFFFF16 :00000001FF :00000001FF :00000001FF :00000001FF :00000001FF 0001FF 0001FF 0001FF 0001FF 0001FF 0001FF 0001FF 001FF 001FF 001FF 001FF 001FF 001FF 001FF 001FF 01FF 01FF 01FF 01FF 01FF 01FF 01FF 01FF 01FF F F F F F F F F F F F F F F F F F F
电子制作可以这么简单
电子入门学习套装
电子入门学习套装
这是纸质磁力电子积木版本的“电子入门学习套装”,里面有NPN型三极管、PNP型三极管、
大家看看中波发射塔什么样子
大家看看中波发射塔什么样子
我们的自制收音机都是中波的,因为调频收音机电路只能焊接,而且对线路安排要求比较严
从零学磁控电路
从零学磁控电路
读过这个教程以后,即使您一点儿电子电路基础都没有,也能了解磁控开关、三极管的基础
从零学触发式报警器
从零学触发式报警器
使用这个套件能制作一个触发式报警器,就是一碰就会报警的装置。套件内容包括: 电池
自制感应式验电笔
自制感应式验电笔
这个教程教大家用两个三极管,自制一个感应式验电笔,能够测量您家的电线是否有电。套
从零学报警电路
从零学报警电路
即使您没有一点儿电子电路基础,看完本教程,也能学会简单的报警电路,包括一个电子水
从零学延时电路
从零学延时电路
本教程能够让您从零学习简单的延时电路,从零的意思是没有一点儿电子电路基础,看完这
从零学光控电路
从零学光控电路
本教程能够让您从零学习简单光控电路,从零的意思是没有一点儿电子电路基础,看完这个
电子科技小制作入门:电子防盗报警器(简易版)
电子科技小制作入门:电子防盗报警器(简易
这次教大家做一个电子防盗报警器。电路里使用了一个滚动开关,也叫倾斜开关,侧倾开关
电子科技制作入门:自制扬声器
电子科技制作入门:自制扬声器
这次教大家自制一个扬声器。电路跟“自制音乐门铃”是一样的,可以学习简单的三极管放

我爱制作网www.xjbjf.com ( 辽ICP备08007767号 )

GMT+8, 2018-9-17 12:50

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

返回顶部