131 1300 0010
開關(guān)電源
  • 導(dǎo)航欄目
  • 逆變電源
  • 開關(guān)電源
  • 電機(jī)伺服
  • 其他電源
  • ATtiny單片機(jī)電子蠟燭
    ATtiny單片機(jī)電子蠟燭
  • ATtiny單片機(jī)電子蠟燭
  •   發(fā)布日期: 2018-12-12  瀏覽次數(shù): 1,074

    想想當(dāng)你好不容易跟女朋友共度燭光晚餐,卻因?yàn)橄灎T點(diǎn)沒了或打翻著火了,那是一件多么坑爹的事啊!今天為你分享一款自己diy的超自然的燭光蠟燭。

     


    WP_000356.jpg

    ATtiny 電子蠟燭,皮特•米爾斯開發(fā)這個(gè)偉大的蠟燭,正如我們圖片所見到的一樣,但怎樣讓這蠟燭的光芒像傳統(tǒng)的蠟燭一樣閃爍呢。

     


    WP_000370.jpg

    皮特使用一個(gè)高亮的LED和一些模擬的輔助軟件,這樣就使得ATtiny 電子蠟燭的燭光和傳統(tǒng)蠟燭擁有一樣的閃爍的燭光,并且優(yōu)于傳統(tǒng)蠟燭,因?yàn)樗话橛忻骰鸬奈kU(xiǎn)。

     


    WP_000376.jpg

    ATtiny 電子蠟燭最難的部分就閃爍神態(tài)逼真,所以皮特做了一個(gè)蠟燭光檢測(cè)電阻( LDR )和固定電阻作為一個(gè)分壓器。這是作為ATTINY85 ADC之中的一個(gè)輸入端,并離散時(shí)間間隔的進(jìn)行采樣。采樣速率為100毫秒。然后將采集的8bit的電頻值存儲(chǔ)到EEPROM中,以便記錄蠟燭的閃爍圖譜,驅(qū)動(dòng)將其連接的LED、PWM形成通路。在用三節(jié)干電池供電。最后您只需編程程序,然后通過開關(guān)進(jìn)行控制。

     


    WP_000345.jpg

    下面是ATtiny 電子蠟燭的電路圖

     


    ATTiny Candle Sch.jpg

    下面是程序的代碼以及寫入EEPROM的數(shù)據(jù)

    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://petemills.blogspot.com

    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 );

    }

    }

    }

    }

    }

    }

    }

    } }

    } }

    } }

    }


  • ·上一篇:
    ·下一篇:
  • 其他關(guān)聯(lián)資訊
    深圳市日月辰科技有限公司
    地址:深圳市寶安區(qū)松崗鎮(zhèn)潭頭第二工業(yè)城A區(qū)27棟3樓
    電話:0755-2955 6626
    傳真:0755-2978 1585
    手機(jī):131 1300 0010
    郵箱:hu@szryc.com

    深圳市日月辰科技有限公司 版權(quán)所有:Copyright?2010-2023 m.xbquwah.cn 電話:13113000010 粵ICP備2021111333號(hào)