Relay alternative

Hi, I'm new to most of this but trying to learn new things.

I'm working on a project where I need one button to change function after first press and for the remaining time stay as that function.

First it is going to "ground" my reset pin and after boot it is going to ground a other pin. Say io 2 or something. I'm trying to keep my project as small as possible and don't want more than one button.

I was looking at a coil relay where I can change what pin to go to ground by pulling one pin high on my board and there by changing ground from one pin of the relay to the other.

I am looking for something smaller. Mutch smaller.
Anyone know of some kind of device?

Wahren:
I'm working on a project where I need one button to change function after first press and for the remaining time stay as that function.

First it is going to "ground" my reset pin and after boot it is going to ground a other pin. Say io 2 or something.

Hi, and welcome to the forum.

I struggle to understand this.
Maybe you should explain what your project is and what it has to do, without trying to think of a solution.

Or post the code you already have (we help people with code, but generally don't write it for them).
Read the forum rules first.

You might not need a relay.
A button can act as a toggle switch, and different blocks of code can run after that.
Leo..

If I'm understanding this correctly, you want to press the button to reset the arduino, then push the same button again to perform a second function. That doesn't sound doable in code, as resetting it starts it all over again.

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html

If we know what your project is we may be able to suggest different ways to achieve your result.

Can you please tell us your electronics, programming, Arduino, hardware experience?

Thanks.. Tom.. :slight_smile:

Sure, why not? Store a value in EEPROM. After a button press, read the EEPROM value; if it's 255 (0xff) have the code change EEPROM value to 0, and then do a jump to 0 or whatever the software reset equivalent is. After the next button press, read the EEPROM value, if it's 0 then do the other function.

I am running a esp-12 in deep sleep. I going to use a single button to restart it and then if I press the button more times I just want to count upp a timer by using Interrupts and after a time it is going to go back to sleep.

The deep sleep and Interrupts is all done. Now I just need a button to first time trigger the reset pin and the next "infinite" times trigger an interrupt until it goes back to sleep. Then it's supposed to trigger the reset pin again.

Can't you wake it from a pin state change, instead of reset?

I want my esp to be as low powered as possible during sleep. What I understood when reading about esp interrupt sleep it only uses light sleep (0.4ma).
In deep sleep the current is less than 20μa.
Unless I have missed something.

Any other idea's?

Look into using RTC memory.

Youtube

// Per.

Presumably, when the chip is in full sleep mode, all of the output pins are LOW, right?

I'm further assuming (I think I read it above, BICBW), that you pull RESET low to wake the chip up?

If so... what you want is another pin, which the MCU sends HIGH as soon as it's alive. This pin is connected (via a transistor?) in such a way that when the switch is pressed for the second time, it doesn't pull the reset pin down (because current from the now-active pin prevents this). The existing "switch" pin would now operate as normal.

I think you'd need a DPDT or DPST switch to make that work, otherwise the "keepalive" pin would also prevent the switch from pulling the other pin low. Alternatively, why not make the second pin respond to a rising signal; so use the keepalive pin for 2 purposes.

I can try and sketch this idea if it doesn't make sense. I have no idea if it'd work or not...

Cheers,
Ade.

PS - if you can supply some bare-bones code, which puts the MCU to sleep after (say) 30 seconds active & requires a reset to restart, unless a timer is reset by a button press - basically, the core of what you're trying to achieve, I'll breadboard something up to see if I can make it work... just that I've never tried sending an Arduino to sleep before, so I'm not totally sure how to do it.

I will try again.
My code looks somewhat like this

Include "library"

Define button = 2
Define timeout = Millis() + 2000
Define counter = 0

void setup()
{
  "Change button action()"
  ‎
  pin mode (button, output)
  ‎interrupt(button, action)
  ‎
  wifi_setup()
}

void loop()
{
  if(Millis() > timeout)
  ‎{
  ‎   mqtt_publish("/button", Counter)
  ‎   deep_sleep()
  ‎ }
}

void action()
{
  counter ++
  ‎timeout = Millis() + 2000
}

I don't know of any good circuit drawing programs so I used a post-it hope it's clear enough?

OK, rather to my surprise, it works!

Please see attached schematic, note that as I don't have an Arduino footprint in my KiCAD library, I've resorted to using a connector... The pin references to match the schematic are:

Pin 1: Connect to +5V
Pin 2: Connect to Digital Pin 10
Pin 3: Connect to Reset
Pin 4: Connect to Digital Pin 5
Pin 5: Connect to GND

Load the following code (I tested this on an Arduino Nano):

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

#define CANCEL_RESET 10   // Connect to J1 pin 2 on schematic
#define DO_STUFF     5    // Connect to J1 pin 4 on schematic
#define INDICATOR    13

void setup() {
  // Set pin HIGH to hold reset HIGH, even when the button is pressed.
  pinMode(CANCEL_RESET,OUTPUT);
  digitalWrite(CANCEL_RESET,HIGH);

  // Read the button on this pin
  pinMode(DO_STUFF,INPUT);
  digitalWrite(DO_STUFF,LOW);

  // Indicate we did something
  pinMode(INDICATOR,OUTPUT);
  digitalWrite(INDICATOR,LOW);

  Serial.begin(38400);
  Serial.println("Ready.");
  
}

void loop() {
  static unsigned long then = millis();
  static byte counter = 0;
  
  // put your main code here, to run repeatedly:
  if(digitalRead(DO_STUFF) == HIGH) {
    // Recognise the button, wait for it to be
    // released
    Serial.println("Button DOWN!");
    counter = 0;
    digitalWrite(INDICATOR,HIGH);
    while(digitalRead(DO_STUFF)==HIGH) {
      //Don't count time passing while the button's in.
      then=millis();
    }
    digitalWrite(INDICATOR,LOW);
    Serial.println("Button UP!");
  }

  unsigned long now = millis();
  
  if (now-then > 1000) {
    counter++;
    then=now;
    Serial.print("Pulse ");
    Serial.println(counter);
  }
  
  if (counter >= 10) {
    // 30 seconds have elapsed without the button
    // being pressed. So go to sleep now
    Serial.println("Feeling sleepy.....");
    counter=0;
    // First, tell the user we're doing this...
    // by flashing the LED rapidly for 2 seconds
    for(byte i=0;i<10;i++) {
      digitalWrite(INDICATOR,HIGH);
      delay(100);
      digitalWrite(INDICATOR,LOW);
      delay(100);
    }

    // Now sleepybo time
    Serial.println("Zzzzz");
    digitalWrite(CANCEL_RESET,LOW);
    delay(100);
    sleepNow();
    Serial.println("Fast asleep now.");
    
  }
}

void sleepNow()
{
    // Choose our preferred sleep mode:
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
 
    // Set sleep enable (SE) bit:
    sleep_enable();
 
    // Put the device to sleep:
    sleep_mode();
 
    // Upon waking up, sketch continues from this point.
    sleep_disable();
}

Make sure the diode is the right way around (if it's wrong, your MCU will continually reset).

The code above will output a message to the serial port every second (handy for testing, as it flashes the Tx).

If you press the button while the machine is awake, you'll get the button down/button up messages & the timer will reset.

When the timer runs out (30s), it'll flash the LED a few times & fall asleep (proof: You never see the "Fast asleep now" message.

Next time you press the button, it will reset the Arduino, which powers back up.

Since I'm using a boggo Nano, I measured the current usage @ 5v to be approximately 23mA whilst running (maybe 26mA with the button pressed & the lamp lit); this dropped to about 6mA when asleep (I guess most of that is the power light & the regulator?)

Now... hopefully someone can come along & tell me why a) this is a terrible circuit, and b) why it can't work. Because, in all honesty, I'm a bit surprised it DOES work!

There is also a way to actually power the Arduino down entirely, and wake it up with a switch. See this thread. Crossroads posted a circuit at the very bottom, which works like a charm. I have used this circuit, except I used an nCh MOSFET instead of BJT for the driver. It is very simple and inexpensive. I think you could run the top of the switch into another input pin and query it during running. When your timer runs out, turn off the driver and let it power down completely. Except maybe some leakage current from the MOSFET, but that would be less than a uA.