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!
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".
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!
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.