Erratic motor behaviour

Hello,

I am trying to run a motor off cell battery using power saving technique on Attiny85. I started with this simple program to see if the motor runs ok after processor wake up. I do not use battery for tests, I use regular 3.3V power supply. Much to my surprise the motor does not run for 1 sec every time as it is supposed to. Sometimes it runs for 1 sec, but most of the times it runs for much shorter periods. I would also say, that these periods are not the same.

I hooked up motor through ULN2003 Darlington pair chip, running Attiny85 at 8MHz (burned fuses before tests).

I am using Nathan Seidle's example code from here.

#include <avr/sleep.h> //Needed for sleep_mode
#include <avr/wdt.h> //Needed to enable/disable watch dog timer

const byte motor = 0;

ISR(WDT_vect) {
}

void setup()
{
  pinMode(motor, OUTPUT);
  //Power down various bits of hardware to lower power usage  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Power down everything, wake up from WDT
  sleep_enable();
}

void loop() 
{
  ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
  setup_watchdog(6); //Setup watchdog to go off after 1sec
  sleep_mode(); //Go to sleep! Wake up 1sec later and check light

  ADCSRA |= (1<<ADEN); //Enable ADC
  wdt_disable(); //Turn off the WDT!!

 delay(2000); 
 digitalWrite(motor, HIGH);
 delay(1000);
 digitalWrite(motor, LOW);
 delay(500); 
}

//Sets the watchdog timer to wake us up, but not reset
//0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
//6=1sec, 7=2sec, 8=4sec, 9=8sec
//From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void setup_watchdog(int timerPrescaler) {

  if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings

  byte bb = timerPrescaler & 7; 
  if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary

  //This order of commands is important and cannot be combined
  MCUSR &= ~(1<<WDRF); //Clear the watch dog reset
  WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable
  WDTCR = bb; //Set new watchdog timeout value
  WDTCR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int
}

If I use

const byte motor = 3;

and hook up an LED, it flashes as expected without any surprises ... :confused:

Simplified down to this. Still motor turns on for different durations although off pause is held ok. After some time the motor starts running constantly.
:confused: :confused: :confused:

const byte motor = 0;
void setup()
{ pinMode(motor, OUTPUT);
}
void loop() 
{
 delay(2000); 
 digitalWrite(motor, HIGH);
 delay(1000);
 digitalWrite(motor, LOW);
 delay(500); 
}

Could it be that the motor is causing a dramatic voltage drop when operated?

(LED works / motor doesn't)

Did you measure the voltage while the motor is running?

Voltage fluctuates without any pattern. I see 0.4, 0.8, 1.3, 0.5, 3.1V ... If I measure with motor disconnected - everything seems to be allright: I get 3.3V and 0.9V according to program algorithm.

If I connect motor to power supply straight, it works fine. If I connect and disconnect it, it still works as it should work. Maybe a diode in the motor circuit would help? But diode is there in ULM2003.

If the measured values reflect the Arduino VCC,
it will reset (brownout), explaining the behaviour.

I use Attiny85. Its VCC remains stable at 3V, occasionally dropping to 2.8V when motor spins for longer periods (1 sec).

ULN2003, being a Darlington, is a very bad choice for running a low voltage motor as you lose at least a volt in the Darlington and likely much more.