There's a latch (for letters) and a door (for parcels) on the front and another door on the back (for the owner to retrieve his mail).
The ATmega328P is running on batteries, so I'm having it sleep most of the time. Since there are only two interrupts and I'm monitoring three switches, I'm using another digital pin to differenciate letters from parcels. PIN6 is set to be HIGH in the code but is LOW when the door is closed ("NO" PIN of the limit switch). It goes HIGH only when the mailman opens it.
#include <avr/sleep.h>
#include <VirtualWire.h>
int pinEntree = 2;
int pinSortie = 3;
int pinPorteAv = 6;
volatile int int_flag = 0;
const char *lettre = "let";
const char *av = "avt";
const char *arr = "arr";
void entree()
{
int_flag = 1;
}
void sortie()
{
int_flag = 2;
}
void setup()
{
vw_set_tx_pin(4); //Pin d'émission
vw_setup(2000); //Vitesse en bps
pinMode(pinEntree, INPUT_PULLUP);
pinMode(pinSortie, INPUT_PULLUP);
pinMode(pinPorteAv, INPUT_PULLUP);
digitalWrite(pinEntree, HIGH);
digitalWrite(pinSortie, HIGH);
digitalWrite(pinPorteAv, HIGH);
const char *set = "retour"; // To let the user know batteries have been replaced.
for (int k = 0; k < 2; k++)
{
vw_send((uint8_t *)set, strlen(set));
vw_wait_tx();
}
// Serial.begin(9600);
}
void loop()
{
ADCSRA = 0;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
attachInterrupt(0, entree, FALLING);
attachInterrupt(1, sortie, FALLING);
MCUCR = bit (BODS) | bit (BODSE);
MCUCR = bit (BODS);
interrupts();
sleep_cpu();
if(int_flag==1)
{
detachInterrupt(0);
delay(100); // Button bounce. I'm giving the button time to pull pinPorteAv HIGH.
if(digitalRead(pinPorteAv) == LOW)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
// Serial.print(j);
vw_send((uint8_t *)lettre, strlen(lettre)); //Sending via RF
vw_wait_tx(); //Waiting for message to be sent
}
// Serial.println();
delay(2500);
}
}
else if(digitalRead(pinEntree) == LOW)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
// Serial.print(j);
vw_send((uint8_t *)av, strlen(av)); //Sending via RF
vw_wait_tx(); //Waiting for message to be sent
}
// Serial.println();
delay(2500);
}
}
}
else if(int_flag=2)
{
detachInterrupt(1);
delay(50);
if(digitalRead(pinSortie) == LOW)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 4; j++)
{
// Serial.print(j);
vw_send((uint8_t *)arr, strlen(arr)); //Sending via RF
vw_wait_tx(); //Waiting for message to be sent
}
// Serial.println();
delay(2500);
}
}
}
int_flag=0;
}
Everything is working as it should...except that it's drawing 0.135 mA when idling.
If I unplug the pin 6 (open the circuit), the current goes into the unmeasurable (multimeter shows 0.01 µA)...but the Arduino is telling me I get a parcel when it's a letter.
I thought the internal PULLUP would reduce the current but maybe it is the case only when the pin is HIGH? Is there a programming trickery I'm not aware of or should I solder an actual resistor in series between my switch and ground?
Since there are only two interrupts and I'm monitoring three switches, I'm using another digital pin to differenciate letters from parcels.
Why? "You've got mail" means a trip to the mailbox, regardless of whether it's a letter or a package or junk mail.
Because I decided it would work this way
If you receive a parcel in the afternoon it's...well, a parcel. If it's "mail", it's going to be junk.
Why are you attaching and detaching interrupts in loop()?
Because the first thing you should do after the interrupt is triggered is to detach it (to make sure it's not triggered twice) before running the code. Then you reattach it and put the µC to sleep.
Why does retrieving the mail need to wake the Arduino up?
Because the Raspberry Pi that is receiving the message is then deleting the mail (through imap) from the owner's e-mail box.
That way they don't have to do it themselves and the Pi won't send a new snail mail notification if the former letter/package hasn't been retrieved (in case of holidays).
I'd like to center the topic back to my problem: the current draw.
I'd like to center the topic back to my problem: the current draw.
I don't see a difference in the way any of the switches are read. So, I can't see a reason why one of them makes the Arduino draw more current.
The two interrupts are constantly HIGH (i.e. switches are open) and go LOW when a door or the latch are open.
The DigitalPin6 is constantly connected to ground (so it's LOW) and goes HIGH only when the front door is open.
In the first try I made, the PIN6 was behaving like the others (ie. HIGH when idle, LOW when open) but that meant effectively connecting PIN2 and PIN6 together (on the NC pin of the switch) and I was having weird results from that.
Everything is working as it should...except that it's drawing 0.135 mA when idling.
If I unplug the pin 6 (open the circuit), the current goes into the unmeasurable (multimeter shows 0.01 µA)...but the Arduino is telling me I get a parcel when it's a letter.
I thought the internal PULLUP would reduce the current but maybe it is the case only when the pin is HIGH? Is there a programming trickery I'm not aware of or should I solder an actual resistor in series between my switch and ground?
What I take from this that your switch contacts are NC (normally-closed) where one terminal is connected to pin 6 and the other connected to GND. It makes sense that this would "normally" draw 0.135 mA when idling and no current draw when in sleep mode.
You wouldn't want to reverse the logic here or you would get the high current draw when sleeping. If the "on time" is such that 0.135 mA is an issue, you could reduce this by about 5X by not using the internal pullup and use an external 200K pullup resistor with 0.01µF connected from pin 6 to GND. This will filter noise and will have a 2 millisecond response.
EDIT: Umm ... critical information came in (should have read it) ... I'm giving my crystal ball to PaulS (I think it just needs new batteries).
Anyways, you would still have to be careful that any changes don't transfer the high current draw to sleep mode.
This is the case Today. I have 0.135 mA of current draw when the µC is sleeping and nobody is touching anything.
Ahh - I wasn't relating the word "idling" to sleep mode.
Let me reformulate the question:
does current flow through the pullup resistor of the ATmega328P when the pin is connected to ground?
Yes.
if not, is it possible to use some internal thingy or should I connect an actual resistor between PIN6 and my switch?
I think you should connect it so you have the high current draw when µC is running and no current draw when the µC is sleeping. The 0.135 mA current draw won't be very significant if, for example, the µC is running only 10% of the time.
EDIT: As in previous post diagram "SW1" (thanks JimboZA) and use "RISING" to trigger your interrupt.
does current flow through the pullup resistor of the ATmega328P when the pin is connecte
d to ground?
I would say yes, since there's a circuit from high, thru resistor, out the pin, thru closed switch, to ground.
The current seems quite high.
dlloyd:
This is the case Today. I have 0.135 mA of current draw when the µC is sleeping and nobody is touching anything.
Ahh - I wasn't relating the word "idling" to sleep mode.
You're right, that was misleading. I meant "the mailbox is idling", i.e. all doors and latch are closed and PIN6 is pulled to ground.
I think you should connect it so you have the high current draw when µC is running and no current draw when the µC is sleeping. The 0.135 mA current draw won't be very significant if, for example, the µC is running only 10% of the time.
I said earlier I can't do it because that means connecting PIN6 to PIN2 and weird shit happens then.
What I can do though is modify the code and draw PIN6 HIGH only when interrupt 0 is triggered (once a day).
Or solder a 100k resistor in series between the switch and PIN6 (I'd prefer not to have to reprogram the ATmega)?
Or solder a 100k resistor in series between the switch and PIN6 (I'd prefer not to have to reprogram the ATmega)?
If the internal pullup is 50K, then the 100K in series will only swing the voltage down to 1.66V (could be a problem).
With a small change to the code (remove PULLUP) and use an external 100K or 200K pullup (connected pin 6 to 5V, leaving switch connections as is), you should get much less current draw and still have full voltage swing on pin 6. You may need a small capacitor of around 0.01µF to filter any noise and provide hardware debounce.
dlloyd:
With a small change to the code (remove PULLUP) and use an external 100K or 200K pullup (connected pin 6 to 5V, leaving switch connections as is), you should get much less current draw and still have full voltage swing on pin 6.
Understood.
You may need a small capacitor of around 0.01µF to filter any noise
On a simple setup like that running off 3*AAA batteries, is there an actual risk of noise?
All the pins of an ATmega328P are capable of generating a pin-change interrupt. Which would suit your application well. And would eliminate the need to overload any pins.
All the pins of an ATmega328P are capable of generating a pin-change interrupt. Which would suit your application well. And would eliminate the need to overload any pins.[/quote]
Waking-up interrupts?