candle.c


// candle.c

#include "iodefs.h"
#include "crc.h"
#include "rand.h"
#include "timer.h"
#include "uart.h"
#include "show_adc.h"
#include "progmem.h"
#include "adc.h"

#define LOW_POWER

#define delay(x) _delay_ms(x)

//#define BYTE(x) x

int main(void)
{
    unsigned char ix;
    register unsigned short v asm("r2");
    register unsigned short v1 asm("r6");
    register unsigned short v2 asm("r8");
    register unsigned short v3 asm("r10");
    register unsigned short seed asm("r12");
    unsigned short vref;
    register char tic = BYTE('-');
    register unsigned char loop = 0;

    osccal();   // calibrate internal processor clock

    adc_disable();  // disable ADC
    timer1_stop();   // stop timer

    _uart_reset();   // enable UART output

    // delay before driving MOSI output (thermistor driver pin)
    cbi(DDR(TM_PORT),TM_BIT);  // tri-state thermistor driver pin
    sbi(DDR(LED_PORT),LED_BIT);  // make LED driver output
    for (ix = 0; ix < 4; ++ix) {
        if ((ix & 1) == 0)
            cbi(LED_PORT, LED_BIT);       // LED on
        else 
            sbi(LED_PORT,LED_BIT);       // LED off
        delay_cs(25);   
    }
    cbi(TM_PORT,TM_BIT);       // thermistor driver pin low
#ifndef LOW_POWER
    sbi(DDR(TM_PORT),TM_BIT);  // activate thermistor driver pin
#endif

    // setup DAC (PWM mode, active low, fast clock)
    timer1_init(PWM_ON, COM1A_SET, T1_CK, 0, 0);

    // internal ref, left-adjust, free-run, thermistor input, fastest rate
    ///adc_setup(ADC_REF_INT, ADC_LEFT, ADC_BIT, ADC_FREE, ADC_CK2);
    adc_setup(ADC_REF_VCC, ADC_LEFT, ADC_BIT, ADC_FREE, ADC_CK2);
    adc_start();  // start free-running conversion

    dac_set(255);  // LED on bright
    // delay and then read "reference"
    delay_cs(100);   
    sbi(DDR(TM_PORT),TM_BIT);  // activate thermistor driver pin
    delay_ms(10);   
    seed = v1 = v2 = v3 = vref = adc_inputw() >> 6;

    if (seed == 0) seed = BYTE('U');

    puthexb(vref >> 8); puthexb2(vref, ' '); crlf();

    while (1) {
        unsigned char ch, i;
        char n;

#ifndef LOW_POWER
        if ((loop & 127) == 0) {
            tic = BYTE('+');
        }
#endif
        if ((loop & 127) == 63) {
            tic = BYTE('-');
        }
        ++loop;

#define PERIOD 20
        // heat up thermistor
        sbi(DDR(TM_PORT),TM_BIT);  // activate thermistor driver pin
        //delay_ms(PERIOD/2);   
delay_ms(PERIOD);   

        // read next value
        dac_set(0);                 // turn off LED (low noise)
        delay_ms(1);                // wait for ADC reading to complete
        v = adc_inputw() >> 6;      // read ADC
        dac_set(ix);                // LED back on
        puthexb(v >> 8); puthexb2(v, ' ');

        if (tic == '-') {
            cbi(DDR(TM_PORT),TM_BIT);  // deactivate thermistor driver pin
        }

        // calculate delta from reference
        ix = (vref > v) ? vref - v : v - vref;
        puthexb2(ix, tic);

ix = ix << 2;

        // update LED
        seed = rand(seed);
        if      (ix == 0) { ix = (seed & 1) ? 0 : BYTE(40); }
        else if (ix == 1) { ix = BYTE(50); }
        else if (ix == 2) { ix = BYTE(60); }
        else if (ix == 3) { ix = BYTE(70); }
        else if (ix == 4) { ix = BYTE(80); }
        else if (ix == 5) { ix = BYTE(90); }
        else if (ix == 6) { ix = BYTE(100); }
        else if (ix == 7) { ix = BYTE(120); }
        else              { ix = BYTE(126); }
        puthexb2(ix, tic);
        ix = (BYTE(127) - ix) << 1;
        dac_set(ix);

        // plot readings
        n = vref - v;
        for (i = 0; i < 64; ++i) {
            ch = ' ';
            if (i == 32) ch = BYTE('.');
            if (i == 32 + n) ch = BYTE('*');
            putchar(ch);
        }
        crlf();

	// update reference
        vref = (v + v1 + v2 + v3 + BYTE(2)) >> 2;
        v3 = v2;
        v2 = v1;
        v1 = v;

        // wait 
        delay_cs(PERIOD);   
    }
}

Back