Without and of the sleep coding when I press the button my switch pulls the voltage to ground causing it to go low at the switchPin. Then My LED lights up and my mosfet allows power to a solenoid. When I include all the code in the attempt to get the arduino to sleep...it will no longer light the LED or key the mosfet. I'm currently at a loss on this one
/*
* Sleep Mosfet...sleeeep!
*/
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
int switchPin = 2; // switch is connected to pin 2
int mosfetPin = 6;
int ledPin = 10;
int val; // variable for reading the pin status
int buttonState; // variable to hold the button state
int buttonPresses = 0; // how many times the button has been pressed
int sleepStatus = 0;
int count = 0;
void wakeUpNow(void)
{
detachInterrupt(0);
}
void setup() {
pinMode(switchPin, INPUT); // Set the switch pin as input
pinMode(mosfetPin, OUTPUT);
pinMode(ledPin, OUTPUT);
buttonState = digitalRead(switchPin); // read the initial state
}
void sleepNow(void){
attachInterrupt(0, wakeUpNow, LOW);
delay(100);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
sleep_disable();
}
void loop(){
val = digitalRead(switchPin); // read input value and store it in val
if (switchPin = HIGH){
count++;
delay(1000);
if (count >= 60) {
count = 0;
sleepNow();
}
}
if (val != buttonState) { // the button state has changed!
if (val == LOW) { // check if the button is pressed
buttonPresses++;
digitalWrite(ledPin, HIGH);
analogWrite(mosfetPin, 255);
delay(300);
analogWrite(mosfetPin, 127);
}
else
{
digitalWrite(ledPin, LOW);
analogWrite(mosfetPin, 0);
}
}
buttonState = val; // save the new state in our variable
}
interrupt 0 is generated by pin D2, where you have the signal switchPin.
Try moving switchPin to another pin, and do something different with D2 to cause the interrupt.
You can use the internal pullup on D2 and then a button to ground for the interrupt.
What exactly happens when you send a 0% PWM, 50% PWM, and 100% PWM signal to your MOSFET?
Is the solenoid happy with that? Is 100% the kick to get it started, and 50% to hold it?
Then like PaulS says, check what you reading & comparing:
val = digitalRead(switchPin); // read input value and store it in val
if (switchPin = HIGH){ <<<<< probably want "if (val == HIGH)" here instead?
@PaulS Sorry, the if (switchPin = HIGH) statement was a last minute @#$#@$$@ change before I posted and left in a huff. I should have payed closer attention to that. Thanks!
@CR You are gentleman and scholar as usual! So my questions are,
I have the switch set up with a pull-down resistor so my interrupt is always HIGH and will pull the Arduino out of sleep when I activate the solenoid. The button is plugged into switchPin. So would I still need to move my switchPin from D2 or am I basically set?
I've noticed with various sleep code samples that not all of them call the #include <avr/power.h> and #include <avr/interrupt.h>, is this necessary?
I have an N-channel power mosfet connected my Arduino and a pull solenoid. The overall holding force of the solenoid is greater than what I need, the initial force of the solenoid is what's critical to overcome a spring for a locking mechanism. You are correct, the initial burst gets the mechanism unlocked and it drops it to 50% duty cycle for a rather significant amperage savings when at the holding point. The solenoid works just fine with PWM and my understanding is most if not all can operate with PWM. You do lose some Force of course depending on what duty cycle you have your PWM set. It will hum like a transformer in PWM mode. This is a battery operated mechanism so sleep is important for power savings. Also I'm writing and testing this out on my Arduino then transferring it to a Teensyduino. Fun stuff!
I've noticed with various sleep code samples that not all of them call the #include <avr/power.h> and #include <avr/interrupt.h>, is this necessary?
I don't know, but my remote control did not work correctly (go into sleep, or wake up from interrupt) withouth them when I got it working under IDE -0021.
Your statements and your code don't seem consistent.
"I have the switch set up with a pull-down resistor so my interrupt is always HIGH"
So you want the switch closing to cause the LOW to happen for the interrupt.
D2 does not have the internal pullup enabled:
pinMode(switchPin, INPUT); // Set the switch pin as input
digitalWrite(switchPin, HIGH); // <<< add this - enables the pullup to make it high.
Depending on distance away from the switch, an external pullup may be needed, and then just ditch the pulldown altogether.
Sorry CR, I did notice my mistake in nomenclature just after my post and hadn't had a chance to edit it
I believe what I meant to say was I have my button arranged with a pull-up resistor, so the pin is always HIGH, until the button is pressed then goes LOW.
I moved the detachInterrupt() from my void wakeUpNow() to below sleep_disable.
One thing that is not jiving is my previous code, the button and LED response seems erratic. And when the LED does go on, it stays lit for a second, then turns off. My first test version of the code without and sleep programming in there, was fairly responsive to button presses (i.e. I could makes the LED "flash" with semi-rapid button presses, also the solenoid would flick on/and off.)
This code here, everything works as it should but it does not seem to sleep at all. Arduino pulls a steady 49mA and the Teensy is at about 12.8mA with no change over time. I'm basically looking to have it sleep after 5 minutes or so of lack of activity from the button (currently set to one minute so I don't have to stare at it for so long )
/*
* Sleep Mosfet...sleeeep! v4
*/
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
int switchPin = 2; // switch is connected to pin 2
int mosfetPin = 6;
int ledPin = 10;
int val; // variable for reading the pin status
int buttonState; // variable to hold the button state
int sleepStatus = 0;
int count = 0;
void wakeUpNow(void)
{
}
void setup() {
pinMode(switchPin, INPUT); // Set the switch pin as input
pinMode(mosfetPin, OUTPUT);
pinMode(ledPin, OUTPUT);
buttonState = digitalRead(switchPin); // read the initial state
}
void sleepNow(void){
attachInterrupt(0, wakeUpNow, LOW);
delay(100);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
sleep_disable();
detachInterrupt(0);
}
void loop(){
val = digitalRead(switchPin); // read input value and store it in val
if (val != buttonState) { // the button state has changed!
if (val == LOW) { // check if the button is pressed
digitalWrite(ledPin, HIGH);
analogWrite(mosfetPin, 255);
delay(300);
analogWrite(mosfetPin, 127);
}
else
{
digitalWrite(ledPin, LOW);
analogWrite(mosfetPin, 0);
count++;
delay(1000);
if (count >= 60){
count = 0;
sleepNow();
}
}
buttonState = val; // save the new state in our variable
}
}
Your main problem is that the count for sleeping is inside the "if" so you only count when the switch changes state. Try changing loop to:
void loop(){
val = digitalRead(switchPin); // read input value and store it in val
if (val != buttonState) { // the button state has changed!
if (val == LOW) { // check if the button is pressed
digitalWrite(ledPin, HIGH);
analogWrite(mosfetPin, 255);
delay(300);
analogWrite(mosfetPin, 127);
}
else
{
digitalWrite(ledPin, LOW);
analogWrite(mosfetPin, 0);
}
buttonState = val; // save the new state in our variable
}
if (val == HIGH) // switch not pressed
{
count++;
delay(1000);
if (count >= 60){ // 60 seconds up?
count = 0;
sleepNow();
}
}
} // end of loop
You also have a problem with those delays. If you close and open the switch within a second (while doing the delay) you won't notice it. You should really test millis () for time elapsed, rather than doing a delay.
Thank you everyone...this code sample is the WIN. Currently set-up for a teensyduino, it pulls about 13mA nominally, under sleep .7mA. This is a simplified version of what I'm building. I'll show the final piece of code here when I'm done adding the sleep function. Thanks again!
/*
* Sleep Mosfet...sleeeep! v4
*/
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
int switchPin = 5; // switch is connected to pin 2
int mosfetPin = 10;
int ledPin = 1;
int val; // variable for reading the pin status
int buttonState; // variable to hold the button state
int sleepStatus = 0;
int count = 0;
unsigned long firstCount;
unsigned long endCount;
unsigned long finalTime;
void wakeUpNow(void)
{
}
void setup() {
pinMode(switchPin, INPUT); // Set the switch pin as input
pinMode(mosfetPin, OUTPUT);
pinMode(ledPin, OUTPUT);
buttonState = digitalRead(switchPin); // read the initial state
}
void sleepNow(void){
attachInterrupt(0, wakeUpNow, LOW);
delay(100);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
sleep_disable();
detachInterrupt(0);
}
void loop(){
val = digitalRead(switchPin); // read input value and store it in val
if (val != buttonState) { // the button state has changed!
if (val == LOW) { // check if the button is pressed
digitalWrite(ledPin, HIGH);
analogWrite(mosfetPin, 255);
delay(300);
analogWrite(mosfetPin, 127);
}
else
{
digitalWrite(ledPin, LOW);
analogWrite(mosfetPin, 0);
}
buttonState = val; // save the new state in our variable
}
if (val == LOW){
firstCount = millis();
}
if (val == HIGH) // switch not pressed
{
endCount = millis();
finalTime = (endCount - firstCount);
if (finalTime >= 60000){ // 60 seconds up?
sleepNow();
}
}
} // end of loop