motor2.c


// motor2.c

#include "iodefs.h"
#include "timer.h"

//#define PWR_9V
#define PWR_6V

#ifdef PWR_9V
#define MOTOR_PERIOD_SECS 60
#define MOTOR_PULSE_MSECS 100
#define MOTOR_STEP 20
#define MOTOR_LIMIT 20
#define RAMP_MASK 0x1111
#endif

#ifdef PWR_6V
#define MOTOR_PERIOD_SECS 60
#define MOTOR_PULSE_MSECS 100
#define MOTOR_STEP 20
#define MOTOR_LIMIT 40
#define RAMP_MASK 0x0707
#endif

#ifndef RAMP_MASK
#error Please define: PWR_9V or PWR_6V
#endif

//#define TESTING
#ifdef TESTING
#define MOTOR_PERIOD_SECS 5
#define MOTOR_PULSE_MSECS 2000
#endif

/*********************************************************************

   100 msec @ 75 mA every 60 sec => 0.125 mA avg.
   500 mA-hr 9V cell => 4,000 hr => 167 days => 5.5 months
   2000 mA-hr AA cells => 16,000 hr => 667 days => 22 months => 1.85 yrs

   1.5A, 6.5V => 4.3 ohm motor coil
   0.85A, 3.0V => 3.5 ohm motor coil

   30 ms @ 0.8A @ 3V every 60 sec => 0.400 mA avg.
   20 ms @ 1.3A @ 6V every 60 sec => 0.433 mA avg.
   70 ms @ 0.35A @ 1.55V every 60 sec => 0.408 mA avg.
   2500 mA-hr AA cells => 6,250 hr => 260 days => 8.7 months

   "Real" Diva (9V batt, weak ~7V)
   125 mA * 60 msec +  650 mA * 4 msec every 60 sec => 0.168 mA avg.
      0.125 mA      +      0.043 mA                 => 0.168 mA avg.


*********************************************************************/
//
// active low LED push-pull driver
//
#define led_on()  cbi(LED_PORT, LED_BIT)
#define led_off() sbi(LED_PORT, LED_BIT)
#define led_init() sbi(DDR(LED_PORT),LED_BIT); /* LED driver output */ \
                   led_off()

//
// motor with N-chan FET driver
//
#define motor_on()  sbi(MOTOR_PORT, MOTOR_BIT)
#define motor_off() cbi(MOTOR_PORT, MOTOR_BIT)
#define motor_init() sbi(DDR(MOTOR_PORT),MOTOR_BIT); /* motor driver output */ \
                     motor_off()

static void ramp_motor(
    unsigned short msecs,    // number of  milliseconds on
    unsigned char step,      // down-ramp step per msec (percent)
    unsigned char limit      // down-ramp limit (percent)
){
    unsigned char ix;
    unsigned char ramp = 100;

    led_on();
    while (msecs -= BYTE(1)) {
        timer0_start(T0_CK8);
        while (timer0_get() < US2T0CNT8(1000)) {
if (ramp == limit) {
            unsigned short bits = RAMP_MASK;
            for (ix = 0; ix < 16; ++ix) {
                if (bits & 1) motor_on(); else motor_off();
                bits = bits >> 1;
            }
} else {
            for (ix = 0; ix < 100; ++ix) {
                if (ix <= ramp) motor_on(); else motor_off();
                ///if (ix <= ramp) led_on(); else led_off();
            }
}
        }
        ramp -= step;
        if (ramp < limit) ramp = limit;
    }
    motor_off();
    led_off();
}

int main(void)
{
    unsigned char mcusr;
    register unsigned char ix asm("r2");  // don't initialize this!

    osccal();   // calibrate internal processor clock

    mcusr = read_mcusr();

    outb((1 << WDE) | WD_1024K, WDTCR);   // enable watchdog timer

    outb((SM_PWROFF << SM0), MCUCR);      // select power down sleep mode
    sbi(MCUCR, SE);                       // enable sleep mode

    timer1_stop();   // stop timer

    led_init();
    motor_init();

    if ((mcusr & (1 << WDRF)) == 0) {
        ix = 0;

        // pulse LED after reset
        led_on(); delay_cs(1); led_off();
        delay_cs(10);
        led_on(); delay_cs(1); led_off();
        delay_cs(10);
        led_on(); delay_cs(1); led_off();
        delay_cs(10);

        // pulse motor on startup if external reset
        if ((mcusr & (1 << EXTRF)) != 0) {
            ramp_motor(MOTOR_PULSE_MSECS, MOTOR_STEP, MOTOR_LIMIT);
        }
    }

    while (1) {
        ++ix;
        if (ix >= SEC2WDCYC(MOTOR_PERIOD_SECS, WD_1024K)) {
            ix = 0;
            ramp_motor(MOTOR_PULSE_MSECS, MOTOR_STEP, MOTOR_LIMIT);
            //ramp_motor(1000, 1, 1);
        }
        sleep();
    }
}

Back