Using Arduino to ignore button presses

arduino diagram

How I programmed an Arduino to accept a button press and then ignore subsequent button presses

I am working on an art project that involves a button. The button will start the device, but ignore any extra button presses for a set amount of time. This post focuses on my small journey, and a few things I learned along the way.

My Background

I have a very basic knowledge of electronics. I have an Arduino starter kit, and I played around with the tutorials until I understood the basics. After that I moved on. I figured I could always pick it back up again if needed.

The Requirements

  • Start a garage door opener (I’ll refer to it as the “opener” from now on)
  • Use the opener’s wired-button terminals/leads/pins to control it. These are the same leads that you would use hook up to a button on the wall in your house to use your garage door opener.
  • The opener has 2 terminals/leads – if they touch together, the opener will start
  • Use a button to communicate with the Arduino. It will decide if it should (or should not) use those terminals to start the opener

Hardware

I need 2 buttons: One to communicate with the Arduino, and the other one controlled by the Arduino. To do this I need something called a Relay.

What’s a Relay

A Relay is a fancy switch that is controlled by electricity. It does this with an electromagnet. Imagine a light switch – you add some parts so that if you hold a magnet to one side, the switch will flip. Take the magnet away and the switch flips back off. Wrap that into a box and you have a relay.

  • If no electricity is running to the Relay, then there is no magnet. The switch is off
  • If electricity is running to the Relay, then the electromagnet is on. The magnet attracts the switch to the other side and turns the switch on

You can hear a Relay when it switches. It makes a distinct “click” noise. You find them in a lot of everyday things, like your windshield wipers.

That’s the basics. Yet there are a few more features:

  • The Relay can do the exact opposite. It can be ON when no electricity is running, and turn OFF when the electricity is on
  • Relays are used to operate high voltage electronics, while protecting sensitive equipment. The Arduino can only handle about 5 volts. It could never power a household light bulb. To do this you wire the light bulb with the full power, and use a relay to control that power. The Arduino is safely behind the Relay, protected from the high voltage.

A relay typically has 5 pins:

  1. Input 1: the positive (+)
  2. Input 2: the negative (-)
  3. a common (or COM): this is one half of the thing you are switching
  4. Normally Closed (or N/C): when power is on, the switch is on
  5. Normally Open (or N/O): when power is off, the switch is on

I read a couple articles before this started making sense to me. This one helped me the most: https://www.instructables.com/id/How-Electronic-Switches-Work-For-Noobs-Relays-and/

My Relay

My Relay had no labels and looked different from most of the tutorials. I figured it out by connecting a couple alligator clips to a 9v battery. After connecting them to the pins on the relay, I listened for the click of the magnetic switch. After that I used my volt meter to determine which pins were Normally-Closed and Normally-Open.

The hardware layout

Relay Setup:

  • I connected my ~5 on the Arduino to one pin on the relay, and 5v on the Arduino to the other pin
  • The Common (middle) lead connects to one terminal on the garage door opener
  • The N/C (Normally Closed) pin connects to the other terminal on the garage door opener

Button Setup:

  • The button setup is like all the other button tutorials
  • I connected ground (GRD) on the Arduino to one end of the button
  • I connected ~9 on the Arduino to the other end of the button
My first time drawing a diagram in fritzing!

The Code

Intended behavior:

  1. When the button is pressed (or LOW) on ~5, I trigger a “button press” using the relay for the garage door opener (it starts)
  2. I then run a delay for a set amount of time
    • the delay allows my code to ignore everything until after the delay has finished

Quick notes:

  • I use the built-in LED on the Arduino to show when it is ignoring button presses (LED_BUILTIN)
  • I write debug messages to the serial. Not a big deal but it makes the code a little more busy looking
/**
 * Ignore button presses after accepting the first, for a set amount of time
 * Jason Jerome
 */

int gDoorPin = 5;
int buttonPin = 9;

String msg = "seconds to wait: ";
int secondsToWait = 20;

void setup()
{
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(gDoorPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  digitalWrite(gDoorPin, HIGH);
  Serial.println("Hi - ready");
}

void loop()
{
  if (digitalRead(buttonPin) == LOW)
  {
    Serial.println("button pressed");
    digitalWrite(LED_BUILTIN, HIGH);

    startOpener();

    Serial.println(msg + secondsToWait);
    delay(secondsToWait * 1000);

    Serial.println("done - ready for more");
    digitalWrite(LED_BUILTIN, LOW);
  }
}

void startOpener() {
  Serial.println("gDoor - activating");
  digitalWrite(gDoorPin, LOW);
  delay(500);
  digitalWrite(gDoorPin, HIGH);
}

Here’s a video of it in action:

This has been a fun project so far. I’m very happy to have most of the electronics figured out so early in the process. I can now move on to designing and building the other parts!

A crash course in Flutter

I gave a presentation about Flutter. It’s a lightweight overview, with a short discussion afterwords.
 
I learned Flutter for a client who wanted to explore it for a project they had in mind. They wanted someone with knowledge of Android, iOS, and anything else that might come up. Learning Flutter was a lot of fun! I have been on a few mobile projects since then where Flutter might have made a lot of sense. It would be great to get the chance to use it again in the future.
 
You can view the presentation below. I should note that I had to put it together on short notice. I would have liked to have had a more organized demo, but the presentation still works.

While you are here…

While working with Flutter, I created an open-source project for validating a Drop Down in Flutter.  You can view it on my github page: https://github.com/jjerome00/dropdown_formfield_demo

Flappy Ghost

In my series of games you can’t lose, I modified a version of Flappy Bird and made it so you can’t lose.

This is an overview of the funnest parts of the project for me. If you want to see the details, review my code on github: https://github.com/jjerome00/FlappyGhost

I started with a clone of Flappy Bird called Flappy Cow, written by Lars Harmsen. I have never met Lars, but he seems to be a very talented developer.

His clone has a different theme than the original Flappy Bird. He uses trees and spiders for the obstacles, and a cow instead of a bird. You could also die. I had to change all these things.

Sprite sheet

My first order of business was to make the clone look more like the original game. This meant tracking down a lot of the artwork from the original game. I also got to play around with a sprite sheet.

The cow shown on the screen is using what’s called a sprite sheet. A sprite sheet is one big image that contains all the movements of a character. This way you only need to use one file for all your character’s movements. It’s easier to deal with.

I constructed my own sprite sheet for the bird using the same pattern in the sheet to make the bird’s wings flap. It involved lots of fun with Gimp.

FlappyGhost-bird-spritesheet
Lining up the birds. Notice the wings moving from top to bottom.

Death becomes her

There are a few ways you could die in the game:

Touching the sky
A side effect of not being able to die is that the bird can fly off the screen. You continue flying higher and higher without any repercussions.

I fixed this by modifying the collision checking and touch events. If you touched the top of the screen, that meant you were tapping too much. So I ignore the next tap. This gives the bird enough time to drop from the sky to avoid going off screen.

Touching the ground
When the game detects a collision with the ground, I add an extra tap to keep the bird from ever touching the ground.

Running into a pipe
When the bird runs into a pipe, I thought it would be funny to have the bird change into a ghost. It would glide right through the pipe as if it wasn’t there. That’s where the “Flappy Ghost” name came from.

Ghost Bird
I wanted the bird to change into a ghost when it ran into a pipe. I thought it would be funny for the bird to look like it turned into a silly representation of a ghost. I added a little bit of translucency and a silhouette of a sheet over top.

It turns out the code already provided a nice way to achieve this. There was a feature to add accomplishments to the cow in the original Flappy Cow game. At a certain score the cow would get a hat or sunglasses. There was even a score that would change the cow to a NyanCat. I used that same logic to switch the bird sprite to the ghost sprite. After the collision with the pipe wasn’t detected anymore, I switch it back to the bird.

Clean up

There were a lot of features in the clone that you would want in a real game – such as an ads, analytics and Play Services. I had to remove everything without breaking the game. It was an interesting mix of learning how the APIs were added, and then figuring out how to remove them without crashing the app.

In Conclusion

I had a lot of fun breaking this app down and building it back up. I learned a few things about writing games, and made changes by leaning on existing features.

As a consultant, I am always writing, testing, and refactoring code to make it the best it can be. It’s fun to ignore most of that and make things work as quick as possible. I think the big lesson is that making something perfect does not always fit the client’s needs.