Community Outreach Project.

Hi all,

I'm fairly new to programming, and I've taught myself as much I can in my time frame. I'm working on a project for the kids at the local YMCA program and need some help. I have an ATTINY that I'm utilizing to control a small servo motor. The setup works well (i.e. code, motor, etc) and is bulletproof with the current hard-wired switch'; when I feed the "arduino" power from the battery source, it kicks into it's loop(s) without fail. However, I want to ditch the switch for a push button to "Turn On/Off" or in lay mans terms, cut the power to the ATTINY. I believe the only way to do this to have the "arduino" enter a sleep mode (or more likely start-off in a Sleep Mode and resume the loops when the button is pushed). Essentially, I want this to act as a "Master On/Off switch" and to override/interrupt the loops that will be active when the users wish to 'Power down" the unit.

Does this sound correct/possible? I can upload a sketch once I know if I'm in the right ballpark. Thanks in advance for sharing your cognitive prowess with someone in need!

-Michael

Let's assume you wire the switch so that it is grounded when you press it (that is, you use the internal pull-up). Details here:

Then when awake you can just test the switch (see if it is LOW) and if so enter sleep mode (after turning off your motors etc. of course).

This is pretty easy to do, details on various pages including mine:

Prior to entering sleep mode set up for an interrupt on LOW (not FALLING) which will wake the processor. (See the above page, part "Waking from sleep with a signal"). You must immediately detach the LOW interrupt (as the example shows) or performance will be severely degraded.

In sleep mode you should get down to a few microamps of current consumption, which is less than normal battery self-discharge anyway.

Of course you can structure your code so that the first thing it does is enter sleep mode, rather than "doing its stuff".

Why not just use a latching pushbutton to turn the power on/off ?

Awesome, thanks for all the info Nick! I'll check it out and do my best to get it working! I'll reply again if or when I trip and fall. UKHeliBob, I need a tiny switch, and I don't think they make one that small...but I'll take a peek again for one as well. Thanks for all the info guys, greatly appreciated!

-Michael

How tiny does it need to be ?

Thanks for all the tips and feedback. I will look into that switch; in the mean time, I pulled some info from Nick's website and culled this info: wanted to know if it looks correct for what I'd need to add to my current working sketch (to make sure I'm on the right track).

//SWITCH HIGH IF PRESSED

const byte switchPin = 8;

void setup ()
  {
  Serial.begin (115200);
  pinMode (switchPin, INPUT);
  }  // end of setup

void loop ()
  {
  if (digitalRead (switchPin) == HIGH)
     {
     Serial.println ("Switch closed.");
     delay (1000); 
     } // end if switchState is HIGH
     
  // other code here ...
   
  }  // end of loop


//THIS CODE TELLS PROCESSOR IF IT'S BEEN LAST TURNED ON OR OFF
const byte switchPin = 8;
byte oldSwitchState = HIGH;  // assume switch open because of pull-up resistor

void setup ()
  {
  Serial.begin (115200);
  pinMode (switchPin, INPUT_PULLUP);
  }  // end of setup

void loop ()
  {
  // see if switch is open or closed
  byte switchState = digitalRead (switchPin);
  
  // has it changed since last time?
  if (switchState != oldSwitchState)
    {
    oldSwitchState =  switchState;  // remember for next time 
    if (switchState == LOW)
       {
       Serial.println ("Switch closed.");
       }  // end if switchState is LOW
    else
       {
       Serial.println ("Switch opened.");
       }  // end if switchState is HIGH
    }  // end of state change
     
  // other code here ...
   
  }  // end of loop


//START SLEEP MODE

#include <avr/sleep.h>

void setup () 
{

  for (byte i = 0; i <= A5; i++)
    {
    pinMode (i, OUTPUT);    // changed as per below
    digitalWrite (i, LOW);  //     ditto
    }
    
  // disable ADC
  ADCSRA = 0;  
  
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();
 
  // turn off brown-out enable in software
  MCUCR = _BV (BODS) | _BV (BODSE);
  MCUCR = _BV (BODS); 
  sleep_cpu ();  

}  // end of setup

void loop () { }


//ENABLES WAKE-UP
#include <avr/sleep.h>

const byte LED = 9;
  
void wake ()
{
  // cancel sleep as a precaution
  sleep_disable();
  // must do this as the pin will probably stay low for a while
  detachInterrupt (0);
}  // end of wake

void setup () 
  {
  digitalWrite (2, HIGH);  // enable pull-up
  }  // end of setup

void loop () 
{
 
  pinMode (LED, OUTPUT);
  digitalWrite (LED, HIGH);
  delay (50);
  digitalWrite (LED, LOW);
  delay (50);
  pinMode (LED, INPUT);
  
  // disable ADC
  ADCSRA = 0;  
  
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
  sleep_enable();

  // Do not interrupt before we go to sleep, or the
  // ISR will detach interrupts and we won't wake.
  noInterrupts ();
  
  // will be called when pin D2 goes low  
  attachInterrupt (0, wake, LOW);
 
  // turn off brown-out enable in software
  // BODS must be set to one and BODSE must be set to zero within four clock cycles
  MCUCR = _BV (BODS) | _BV (BODSE);
  // The BODS bit is automatically cleared after three clock cycles
  MCUCR = _BV (BODS); 
  
  // We are guaranteed that the sleep_cpu call will be done
  // as the processor executes the next instruction after
  // interrupts are turned on.
  interrupts ();  // one cycle
  sleep_cpu ();   // one cycle

  } // end of loop

Thanks in advance for any help; I'm trying to teach myself programming in my little bit of free time when I'm not working and this website/web community has been such an amazing asset.

-Michael