Please help with a sketch (willing to pay)

Hi guys,

totally new to this Arduino world and in need for help :slight_smile:

I need something fairly basic compared to what I've seen on here haha

QUICK description:

  • i have one button that should trigger 3 relays for a second, depending on whether I tap once, twice or thrice
  • the whole thing needs to be in "deep sleep" until the button is used so to conserve energy

Button is on PIN 3 and GND
Relay 1 (needs 5V) on PIN10 + GND
Relay 2 (same) on PIN 11 + GND
Relay 3 (same) on PIN 12 + GND

I'm using the code below and need to integrate that power-savings code, but NO IDEA how, please help :slight_smile:

LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

code below

Do you want help, or do you want someone to do it for you? The reason I ask is because we have many people on this forum who are happy to help people learn for free. We also have a dedicated forum section where you can offer paid work. There are forum members who specifically monitor that forum section and may be willing to do some quality work for a reasonable price. So if you only want to pay someone to do the work for you, I would move your thread to that forum section to make sure the right people see it. But if you want help learning to do the project yourself then this is a reasonable forum section and I would leave it here.

pert:
Do you want help, or do you want someone to do it for you? The reason I ask is because we have many people on this forum who are happy to help people learn for free. We also have a dedicated forum section where you can offer paid work. There are forum members who specifically monitor that forum section and may be willing to do some quality work for a reasonable price. So if you only want to pay someone to do the work for you, I would move your thread to that forum section to make sure the right people see it. But if you want help learning to do the project yourself then this is a reasonable forum section and I would leave it here.

Hey, thanks for the quick reply!

I'd definitely like to learn how to do it, but I have absolutely no idea how difficult it is to get done what I wanted to do. If I'm "too far off" Id have to pay someone to knock it out, but ideally I'd like to do it myself so I can use it for other applications as well.

The code above is from some tutorial I read and I modified it for my application, but I haven't found any samples yet how to integrate the sleep-mode so I could piece it together lol

Ok, well since you're interested in learning, how about we leave it here for now. If you end up deciding you want to just go with the pay route, just click the "Report to moderator" link on this thread and request that it be moved to the Gigs and Collaborations section.

depending on whether I tap once, twice or thrice

That system has great potential for confusing the user - it sounds straightforward but in practice it would be very easy for the user to make a mistake.

The code in this link illustrates how to deal with different button clicks

...R

1. Your sketch should have the following appearance

#define sw 5 //pin at push sw is connected
#define one 10
#define two 11
#define three 12

bool lastButtonState = HIGH;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
bool buttonState = HIGH; //saving state of the switch
byte tapCounter; //for saving no. of times the switch is pressed
int timediff; //for saving the time in between each press and release of the switch
bool flag1, flag2; //just two variables
unsigned long presstime, releasetime; //for saving millis at press and millis at release

void setup()
{
  Serial.begin(9600); //for serial monitor
  pinMode(sw, INPUT_PULLUP); //setting pin 5 as input with internal pull up resistor
  pinMode(one, OUTPUT); digitalWrite(one, LOW);
  pinMode(two, OUTPUT); digitalWrite(two, LOW);
  pinMode(three, OUTPUT); digitalWrite(three, LOW);
}

void loop()
{
  bool reading = digitalRead(sw);

  if (reading != lastButtonState)
  {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (reading != buttonState)
    {
      buttonState = reading;
    }
  }
 
  if (buttonState == 0 && flag2 == 0)
  {
    presstime = millis(); //time from millis fn will save to presstime variable
    flag1 = 0;
    flag2 = 1;
    tapCounter++; //tap counter will increase by 1
  }

  if (buttonState == 1 && flag1 == 0)
  {
    releasetime = millis(); //time from millis fn will be saved to releasetime var
    flag1 = 1;
    flag2 = 0;
    timediff = releasetime - presstime; //here we find the time gap between press and release and stored to timediff var
  }

  if ((millis() - presstime) > 400 && buttonState == 1) //wait for some time and if sw is in release position
  {
    if (tapCounter == 1) //if tap counter is 1
    {
      if (timediff >= 400) //if time diff is larger than 400 then its a hold
      {
        Serial.println("Hold");
        hold(); //fn to call when the button is hold
      }
      else //if timediff is less than 400 then its a single tap
      {
        Serial.println("single tap");
        singleTap(); //fn to call when the button is single taped
      }
    }
    else if (tapCounter == 2 ) //if tapcounter is 2
    {
      if (timediff >= 400) // if timediff is greater than  400 then its single tap and hold
      {
        Serial.println("single tap and hold");
        tapAndHold(); //fn to call when the button is single tap and hold
      }
      else // if timediff is less than 400 then its just double tap
      {
        Serial.println("double tap");
        doubleTap(); //fn to call when doubletap
      }
    }
    else if (tapCounter == 3) //if tapcounter is 3 //then its triple tap
    {
      Serial.println("triple tap");
      tripleTap(); //fn to call when triple tap
    }
    else if (tapCounter == 4) //if tapcounter is 4 then its 4 tap
    {
      Serial.println("four tap");
      fourTap();//fn to call when four tap
    }
    tapCounter = 0;
  }
  lastButtonState = reading;
}

void nolight()
{
  digitalWrite(one, LOW);
  digitalWrite(two, LOW);
  digitalWrite(three, LOW);
}

void singleTap()
{
  nolight();
  digitalWrite(one, HIGH);
  delay(1000);
  digitalWrite(one, LOW);
}

void doubleTap()
{
  nolight();
  digitalWrite(two, HIGH);
  delay(1000);
  digitalWrite(two, LOW);
}

void tripleTap()
{
  nolight();
  digitalWrite(three, HIGH);
  delay(1000);
  digitalWrite(three, LOW);
}

2. Now, describe in plain English step-by-step about the purpose of your program.
3. There are three functions in your sketch that have not been defined. Can you tell the names of theses functions?

bool lastButtonState = HIGH;
...
bool buttonState = HIGH;

Oops

GolamMostafa:
1. Your sketch should have the following appearance

#define sw 5 //pin at push sw is connected

#define one 10
#define two 11
#define three 12

bool lastButtonState = HIGH;  // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
bool buttonState = HIGH; //saving state of the switch
byte tapCounter; //for saving no. of times the switch is pressed
int timediff; //for saving the time in between each press and release of the switch
bool flag1, flag2; //just two variables
unsigned long presstime, releasetime; //for saving millis at press and millis at release

void setup()
{
  Serial.begin(9600); //for serial monitor
  pinMode(sw, INPUT_PULLUP); //setting pin 5 as input with internal pull up resistor
  pinMode(one, OUTPUT); digitalWrite(one, LOW);
  pinMode(two, OUTPUT); digitalWrite(two, LOW);
  pinMode(three, OUTPUT); digitalWrite(three, LOW);
}

void loop()
{
  bool reading = digitalRead(sw);

if (reading != lastButtonState)
  {
    lastDebounceTime = millis();
  }

if ((millis() - lastDebounceTime) > debounceDelay)
  {
    if (reading != buttonState)
    {
      buttonState = reading;
    }
  }

if (buttonState == 0 && flag2 == 0)
  {
    presstime = millis(); //time from millis fn will save to presstime variable
    flag1 = 0;
    flag2 = 1;
    tapCounter++; //tap counter will increase by 1
  }

if (buttonState == 1 && flag1 == 0)
  {
    releasetime = millis(); //time from millis fn will be saved to releasetime var
    flag1 = 1;
    flag2 = 0;
    timediff = releasetime - presstime; //here we find the time gap between press and release and stored to timediff var
  }

if ((millis() - presstime) > 400 && buttonState == 1) //wait for some time and if sw is in release position
  {
    if (tapCounter == 1) //if tap counter is 1
    {
      if (timediff >= 400) //if time diff is larger than 400 then its a hold
      {
        Serial.println("Hold");
        hold(); //fn to call when the button is hold
      }
      else //if timediff is less than 400 then its a single tap
      {
        Serial.println("single tap");
        singleTap(); //fn to call when the button is single taped
      }
    }
    else if (tapCounter == 2 ) //if tapcounter is 2
    {
      if (timediff >= 400) // if timediff is greater than  400 then its single tap and hold
      {
        Serial.println("single tap and hold");
        tapAndHold(); //fn to call when the button is single tap and hold
      }
      else // if timediff is less than 400 then its just double tap
      {
        Serial.println("double tap");
        doubleTap(); //fn to call when doubletap
      }
    }
    else if (tapCounter == 3) //if tapcounter is 3 //then its triple tap
    {
      Serial.println("triple tap");
      tripleTap(); //fn to call when triple tap
    }
    else if (tapCounter == 4) //if tapcounter is 4 then its 4 tap
    {
      Serial.println("four tap");
      fourTap();//fn to call when four tap
    }
    tapCounter = 0;
  }
  lastButtonState = reading;
}

void nolight()
{
  digitalWrite(one, LOW);
  digitalWrite(two, LOW);
  digitalWrite(three, LOW);
}

void singleTap()
{
  nolight();
  digitalWrite(one, HIGH);
  delay(1000);
  digitalWrite(one, LOW);
}

void doubleTap()
{
  nolight();
  digitalWrite(two, HIGH);
  delay(1000);
  digitalWrite(two, LOW);
}

void tripleTap()
{
  nolight();
  digitalWrite(three, HIGH);
  delay(1000);
  digitalWrite(three, LOW);
}



**2.** Now, describe in plain English step-by-step about the purpose of your program.
**3.** There are three functions in your sketch that have not been defined. Can you tell the names of theses functions?

Hey,

sorry for the late reply. I tinkered around a little bit and someone helped with a code, but it's wildly unreliable.
I had to put in a 390 ohm pull-up to pin 2 otherwise the whole thing would trigger by just touching a wire lol

IN ENGLISH:

I have 1 momentary button, depending on whether I tap this button ONCE, TWICE or THRICE I'd need 5V on PIN10, 11 or 12 respectively for 0.5seconds to trigger a relay attached to those pins.

Here's the code I have right now, sometimes it fires relay 1 after pressing button twice (I guess 1 push to wake the system up?), but this isn't repeatable, so no good :frowning:

#include <avr/sleep.h>


const byte input_button = 3,   // other pin connected to Gnd
           interrrupt_pin = digitalPinToInterrupt(input_button),

           relays[] = {8, 10, 11, 12};  // note 8 is dummy pin, not to be used

volatile bool button_pressed = false;

const bool relay_high = HIGH,
           relay_low = ! relay_high;

uint32_t debounce = 100,  // for button press
         relay_hold = 500,  // in millisecs
         deciding_delay = 3000;  // time to wait for the next button tap

uint32_t last_pressed;

bool sleep_now = false;

byte press_times = 0;


void setup() {

  //Serial.begin(115200);
  //Serial.println("booting...");

  digitalWrite(input_button, HIGH); // high all the time


  for ( byte x = 0; x < 3; x++ ) {
    pinMode(relays[x], OUTPUT);
    digitalWrite(relays[x], relay_low);
  }


  attach_();
}



uint32_t prev2;


void loop() {

  if ( millis() - prev2 >= (2 * deciding_delay) || sleep_now ) { // give 5 secs of activity
    power_down();
  }

  decision();

}



void  power_down() {  // wakes up on pin falling on sensor
  press_times = 0;
  //Serial.println(F("sleeping..."));
  delay(10);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  attach_();
  sleep_mode(); // here the device is actually put to sleep

  //PROGRAM CONTINUES FROM HERE AFTER
  sleep_disable();
  detach_();
  delay(10);
  //Serial.println(F("just woke up..."));
  sleep_now = false;
  awoke_();
}


void awoke_() {
  if ( button_pressed  ) {  // debounce of 100 ms
    deez();
    button_pressed = false;  // resets it
  }
}



void deez() {
  delay(debounce);
  prev2 = millis();
  last_pressed = millis();
  press_times++;
  //Serial.println(press_times);
}



void decision() {

  if ( digitalRead(input_button) == LOW ) {
    deez();
  }

  static byte mee;

  if ( millis() - last_pressed >= deciding_delay ) {
    if ( mee != press_times ) {
      mee = press_times;
      //Serial.println(relays[press_times]);
      digitalWrite(relays[press_times], relay_high); // press_times = 1 for relay[0]
      delay(relay_hold);
      digitalWrite(relays[press_times], relay_low);  // then back to low
      sleep_now = true;
    }
  }


  if ( press_times > 3 ) {
    press_times = 1;
  }

}


void attach_() {
  attachInterrupt(interrrupt_pin, handle_ISR , FALLING );
}

void detach_() {
  detachInterrupt(interrrupt_pin);
}


void handle_ISR () {
  button_pressed = true;
}

Please read How to use this forum - please read. - Installation & Troubleshooting - Arduino Forum, specifically point #7 about posting code so [x] does not mangle your code in the forum and it's easier for us to copy.

Updated! thanks for the info :slight_smile:

So the code works on the serialmonitor, but as soon as its on the bench its hit or miss... I cannot get this button to read properly. Went thru 4 different boards now!

Matce:
So the code works on the serialmonitor, but as soon as its on the bench its hit or miss

Have you tried changing the bench?

@Matce

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Please READ THIS POST to help you get the best out of the forum.

Bob.

TheMemberFormerlyKnownAsAWOL:
Have you tried changing the bench?

cool, so you're the funny one on this board.
noted.

7 day holiday for Matce.
Maybe now he will read the link provided to him.

I seems the 7 day ban ballscrewbob intended to impose didn't work on the first try. Perhaps it's debatable whether it was warranted at that time, but I think Matce2 has certainly earned it now.

@Matce2 I hope the next week away from the forum will give you time to cool off and come back with a more polite, positive approach to working with others on this forum so that we can move past this unpleasantness and get back to helping you with your project.

Sock puppet totally deleted.