Pages: 1 [2]   Go Down
Author Topic: Servo power down / current drain / watchdog timer attiny85  (Read 4092 times)
0 Members and 1 Guest are viewing this topic.
Anacortes, WA
Offline Offline
Full Member
***
Karma: 2
Posts: 163
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You say you just want the servo to do a couple swipes? You -could- just hard code about a second of 1ms pin highs, then about a second of 2ms pin highs and be done with it.

Unless you are interested in controlling the actual servo position, then this wouldn't work.

-jim lee
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Jim, the servo hits a switch as well, so controlling position is important.  Good to know though.

cheers

Mark.
Logged

Anacortes, WA
Offline Offline
Full Member
***
Karma: 2
Posts: 163
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Servos stop within 20ms if you stop sending pulses..

maybe this would do it for you?

while(digitalRead(swithcPin1)) sendPulse(1);

then the other end would be..

while(digitalRead(swithcPin2)) sendPulse(2);

-jim lee
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm... No luck as yet.

Using what I think is a fairly bare bones version of the code; it's still not working for me.  I'm not sure if I've inserted the mentioned lines in the correct positions, but it still draws power throughout the sequence.  If I try to inesert myServo.detach(); anywhere, the servo will not move at all.

Can anyone see where I am going wrong here?  I tried to add Nicks lines too, however I obviously need to create some sort of variable for that to work?

Thanks,

Mark.

Code:
/*
 * Watchdog Sleep Example
 * Demonstrate the Watchdog and Sleep Functions
 * LED on digital pin 0
 *
 * KHM 2008 / Lab3/  Martin Nawrath nawrath@khm.de
 * Kunsthochschule fuer Medien Koeln
 * Academy of Media Arts Cologne
 *
 * XXXXXXXXXXXXXXXXXXX originally by InsideGadgets (www.insidegadgets.com)
 * to suit the ATtiny85 and removed the cbi( MCUCR,SE ) section
 * in setup() to match the Atmel datasheet recommendations
 */

#include <avr/sleep.h>
#include <avr/wdt.h>

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#include "Servo8Bit.h"

Servo8Bit myServo;  //create a servo object.
                    //a maximum of five servo objects can be created


int pinLed = 0;
//create the variable, init it to zero.
uint8_t originalValue = 0;
volatile boolean f_wdt = 1;

void setup(){
  pinMode(pinLed,OUTPUT);
  setup_watchdog(8); // approximately 4 seconds sleep
    }

void loop(){
  if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
    f_wdt=0;       // reset flag
 //Restore the TCCR1 register to re-enable the timer.
TCCR1 = originalValue;
//reattach the servo that was previously detached
    myServo.attach(1,544,2200); //attach the servo to pin PB1
    digitalWrite(pinLed,HIGH);  // let led blink
        for(int pos = 0; pos < 180; pos++)  // goes from 0 degrees to 180 degrees
    {                                   // in steps of 1 degree
        myServo.write(pos);             // tell servo to go to position in variable 'pos'
        delay(15);                      // waits 15ms for the servo to reach the position
    }

    for(int pos = 180; pos > 1; pos--)  // goes from 180 degrees to 0 degrees
    {
        myServo.write(pos);             // tell servo to go to position in variable 'pos'
        delay(15);                      // waits 15ms for the servo to reach the position
    }
    digitalWrite(pinLed,LOW);
    //save the value of the Timer Counter Control Register 1
    originalValue = TCCR1;
    //turn off timer 1
    TCCR1 = 0; //turn off timer 1
    pinMode(pinLed,INPUT); // set all used port to intput to save power
    system_sleep();
    pinMode(pinLed,OUTPUT); // set all ports into state before sleep
  }
}

// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {
  cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF

  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
  sleep_enable();

  sleep_mode();                        // System sleeps here

  sleep_disable();                     // System continues execution here when watchdog timed out
  sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
}

// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
  int ww;
  if (ii > 9 ) ii=9;
  bb=ii & 7;
  if (ii > 7) bb|= (1<<5);
  bb|= (1<<WDCE);
  ww=bb;

  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCR = bb;
  WDTCR |= _BV(WDIE);
}
  
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}



Moderator edit: [code] [/code] tags added.
« Last Edit: March 11, 2012, 11:08:56 pm by Coding Badly » Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19065
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, get rid of the smiley-faces. Edit your post, select the code, and hit the "#" button to put it into [ code ] tags.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

righto, cheers Nick.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19065
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well I've made a few changes (so I could understand it basically) and tested with my Attiny85 I happened to have lying around. smiley

Code:
#include <avr/sleep.h>
#include <avr/wdt.h>
#include "Servo8Bit.h"

Servo8Bit myServo;  //create a servo object.
int pinLed = 0;

void setup()
  {
  pinMode(pinLed,OUTPUT);
  }  // end of setup

void loop()
  {
  //reattach the servo that was previously detached
  myServo.attach(1,544,2200); //attach the servo to pin PB1

  digitalWrite(pinLed,HIGH);  // let led blink
  for(int pos = 0; pos < 180; pos++)  // goes from 0 degrees to 180 degrees
    {                                   // in steps of 1 degree
    myServo.write(pos);             // tell servo to go to position in variable 'pos'
    delay(15);                      // waits 15ms for the servo to reach the position
    }

  for(int pos = 180; pos > 1; pos--)  // goes from 180 degrees to 0 degrees
    {
    myServo.write(pos);             // tell servo to go to position in variable 'pos'
    delay(15);                      // waits 15ms for the servo to reach the position
    }
  digitalWrite(pinLed,LOW);

  myServo.detach ();

  //save the value of the Timer Counter Control Register 1
  byte saved_TCCR1 = TCCR1;
  //turn off timer 1
  TCCR1 = 0; //turn off timer 1
 
  pinMode(pinLed,INPUT); // set all used port to intput to save power
 
  system_sleep();
 
  pinMode(pinLed,OUTPUT); // set all ports into state before sleep
  //Restore the TCCR1 register to re-enable the timer.
  TCCR1 = saved_TCCR1;
}  // end of loop

// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep()
  {
  // disable ADC
  byte saved_ADCSRA = ADCSRA;  
  ADCSRA = 0;

  // clear various "reset" flags
  MCUSR = 0;    
  // allow changes, disable reset
  WDTCR = _BV (WDCE) | _BV (WDE);
  // set interrupt mode and an interval
  WDTCR = _BV (WDIE) | _BV (WDP3) | _BV (WDP0);    // set WDIE, and 8 seconds delay
  wdt_reset();  // pat the dog
  
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  

  sleep_enable();
  sleep_cpu ();  
  sleep_disable();

  ADCSRA = saved_ADCSRA;
  }  // end of system_sleep

// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect)
  {
   wdt_disable();  // disable watchdog
  }   // end of WDT_vect

I didn't quite get what the flag was for the watchdog, so that went out the window. And a few other things I didn't get either.

I'm not quite sure about the servo output. I'm seeing about 25 pulses of about 1.54 mS high each followed by 18.76 mS low, per batch.

With the LED disconnected the circuit draws about 8.8 mA when active, and about 675 uA when sleeping. Is that roughly what you are expecting? With the LED on pin 5 it draws 16.5 mA (that would vary depending on the resistor on the LED).

(edit) See below for corrected figures.
« Last Edit: March 12, 2012, 01:29:16 am by Nick Gammon » Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm... I can't believe you could take half a look at that mess and create something tangible.

Thanks for your help, I'm looking forward to sitting down and trying to figure out what's going on and where I was going wrong.

I hope this little exercise will help someone else.

Hat's off to you mate.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19065
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I made a major cock-up of the measurements. I had left in the circuit on the breadboard an IR sensor from a previous experiment that was drawing current.

The revised figures are:

  • Sleeping: 8 uA
  • Awake (with no LED): 8.1 mA

Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just a quick update...

I had Nick's code running fine yesterday, however today when I tried it, it was a no go again.  Tried on a couple of different chips and rewired a dozen times so who knows what's going on there.

Went back to the code I'd posted above.  The trick is not so much in the detachment of the servo after all that, it is to put a protection diode on the pin controlling the servo .

Testing on my desk at the moment and working fine.  Figured this out as there was no current when the red to the servo was detached, but remained current draw when the brown was.

Trick for young players I guess.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19065
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep the old protection diode. An oldie but a goodie.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm....

The plot thickens...

The unit is kind of functioning, however when running through the MOSFET, it crashes after a few cycles (not many, maybe 5 - 20).

Because I'm running with the LED of the gate pin for the MOSFET, I can see the LED behaves strangely when it crashes, either flickering a bit, staying on continuously, or staying off.  I should point out it would function correctly up until this point.

Voltage is fine, around 5v, however different power supplies seem to result in the same issues.

Odd, but no doubt common... I thought best to continue this thread? 

Is this likely a stack thing, or a resistor pull-down thing (which I don't completely understand, but think I have right), or something else entirely?

Cheers, Mark.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 499
Posts: 19065
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What's your circuit?

This is how I am wiring up MOSFETs in this situation:



The 10 ohm series resistor limits current out of the processor, and the 10K pulls the gate low when the chip is off/asleep.

In your case you would have the servo where "Load" is.
Logged


Pages: 1 [2]   Go Up
Jump to: