Remote Controlled Stopwatch: the Beginning of a Magical Journey

by thekevalian in Circuits > Arduino

112 Views, 1 Favorites, 0 Comments

Remote Controlled Stopwatch: the Beginning of a Magical Journey

IMG_3140.jpg

Imagine we're on an exciting adventure to create a super cool remote-controlled stopwatch! First up, we'll start with a magical 4-digit seven-segment display that will show us some awesome numbers. Then, we'll add a buzzer that makes funny sounds. Finally, to make our stopwatch even more amazing, we'll put in an invisible sensor and a magical remote control. Get ready for a fantastic journey as we build our awesome remote-controlled stopwatch step by step!

Supplies

Arduino Uno (1)

100 ohm resistor (1)

4 digit 7 segment display(1)

passive buzzer (1)

IR Sensor (1)

IR Remote (1)

Enchanting Digits: Adding the 4-Digit Seven-Segment Display

Copy of MISA 7-Segment 4-Digit LED Display.png

First, we'll be setting up our 4-digit seven segment display. Imagine these displays as magical windows that can show us different numbers. Our goal is to create a spell that makes these numbers appear on our very own four-digit seven-segment display!

You will need to install the SevSeg Library in Sketch=>Manage Libraries (I used version 3.7.0)

Now, each segment of our display is like a tiny part of a puzzle, and when we light up specific segments, they come together to form different numbers. Let's take a peek at the spellbook (code) we'll use to make this happen:


const byte SS_D1_PIN = 7;
const byte SS_A_PIN = 6;
const byte SS_F_PIN = 5;
const byte SS_D2_PIN = 4;
const byte SS_D3_PIN = 3;
const byte SS_B_PIN = 2;
const byte SS_E_PIN = A0;
const byte SS_D_PIN = A1;
const byte SS_DP_PIN = A2;
const byte SS_C_PIN = A3;
const byte SS_G_PIN = A4;
const byte SS_D4_PIN = A5;
SevSeg sevseg;

This part of our spellbook tells the display which pins to use for each segment. It's like giving each puzzle piece a specific place to light up. Each letter represents a segment, and when you give it voltage (if it's a common cathode type) or set it to ground (if it's a common anode type) it will turn on. The D1-D4 tell us which digits are on at a certain time.

Next, we have a magical incantation (setup) to prepare our display:

void setup() {
// ... (other spells)
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
sevseg.setBrightness(60);
}

In this part, we're telling the display how to organize itself and how bright it should shine. Just like telling our display to get ready for the magical show!

Now, the real fun happens in our loop:

void loop(){
int thetime = (millis()/10)%10000;
sevseg.setNumber(thetime,2); // set the characters/numbers to display.
sevseg.refreshDisplay();
}

Here, we're telling the display which numbers to show. The above code displays 0 to 99.99 seconds and restarts because

  1. Time:
  2. millis() / 10: The millis() function is like a clock, revealing the number of milliseconds that have passed since our Arduino awakened. Dividing this by 10 is to slow down time to only care about hundredths of a second.
  3. % 10000: The modulus operation ensures that our numbers stay within the range of 0 to 9999.
  4. int thetime: Represents the time in hundredths of a second.
  5. Number Conjuring:
  6. sevseg.setNumber(thetime, 2): With a wave of our digital wand, we instruct the seven-segment display to display thetime. The '2' signifies the number of decimal places.
  7. Display Illumination:
  8. sevseg.refreshDisplay(): Here, the grand finale unfolds as we command the display to refresh and illuminate with the magical numbers we've summoned, creating a visual spectacle.

Try out for yourself! Check out the circuit diagram for connections and the attached SevenSegmentExample.ino sketch to see it with your own eyes.

If you'd like to learn more about seven segment displays, please check out this.

Incorporating the Maybe? Delightful Buzzer

Copy of MISA 7-Segment 4-Digit LED Display (1).png

Let's integrate the piezo buzzer into your existing magical loop:

void loop() {
  // Capture the essence of time
  int thetime = (millis() / 10) % 10000;

  // Check if it's a magical moment (when time resets)
  if (thetime == 0) {
    // Summon a delightful tone from the enchanted piezo buzzer
    toneAC(440, 10, 1000);
  }

  // Set the numbers to be displayed on our mystical seven-segment display
  sevseg.setNumber(thetime, 2);

  // Illuminate the display with our magical numbers
  sevseg.refreshDisplay();
}


  1. Magical Moment Check:
  2. if (thetime == 0): This spell ensures that our piezo buzzer plays a delightful tone only when the magical moment arrives—when time resets to zero. It adds an extra touch of enchantment to your code.
  3. Buzzer Command:
  4. toneAC(440, 10, 1000): Here, we beckon the piezo buzzer to emit a charming tone. You can customize the frequency (440), volume (10), and duration (1000) to create your own magical melody.

To listen to sounds the buzzer can make:

  • Visit Online Tone Generator.
  • Select "Square" for a magical sound wave.
  • Adjust the number to customize your preferred sound. This number corresponds to the frequency of your enchanting tone.
  • Replace 440 in the toneAC command with the frequency you've chosen.

Now, you have the power to craft your own unique melodies by selecting different frequencies on the tone generator. If you would like to learn more about piezo buzzers, click here

Embrace the Enchantment of Remote Control Exploration!

Copy of MISA 7-Segment 4-Digit LED Display (2).png
me_pressing_buttons.png

Greetings, fellow wizards of the tech realm! Prepare yourselves for a captivating journey into the world of remote control magic. Our arsenal includes an IR transmitter and receiver, mysterious devices that communicate through invisible waves—think of the magic behind TVs or the iconic scene from "Home Alone." Intrigued? You should be! But how does it work? The secret lies in unique codes assigned to each button.

To unveil these magical codes, we wield a special script and the powerful IRremote library, version 4.0.0. This script, when paired with the library, allows us to decipher the mystical language of our remote control. Join us as we decipher codes, cast spells, and unveil the true potential of our magical devices!

#include <IRremote.hpp>
const byte IR_RECEIVE_PIN = 11;
void setup()
{
   Serial.begin(115200);
   Serial.println("IR Receive test");
   IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);
}

void loop(){
   if (IrReceiver.decode())
   {
      byte recieved = IrReceiver.decodedIRData.command;
      Serial.println(recieved);
      IrReceiver.resume();
   }
}

Click each button on your remote while having your serial monitor open and adjust the following switch case statements with your own hex values to indicate which button is being pressed. You may not have the same buttons as I do, so feel free to add more buttons and case statements to accommodate for your remote.

typedef enum remote_button{
  BUT0 = 0,
  BUT1 = 1,
  BUT2 = 2,
  BUT3 = 3,
  BUT4 = 4,
  BUT5 = 5,
  BUT6 = 6,
  BUT7 = 7,
  BUT8 = 8,
  BUT9 = 9,
  BUTPOW = 10,
  BUTVOLP = 11,
  BUTFUNCSTOP = 12,
  BUTREWIND = 13,
  BUTFASTFORWARD = 14,
  BUTPAUSE = 15,
  BUTDOWN = 16,
  BUTUP = 17,
  BUTVOLM = 18,
  BUTEQ = 19,
  BUTSTS = 20,
  BUTTONHELD = 21,
  BUTTONUNKNOWN = 22
 }remote_button_t;

remote_button_t decode(byte val){
    remote_button_t result;
    switch (val){
      case 0x0: // edit 0x0 if needed
        result = BUTTONHELD;
        break;
      case 0x45: // edit 0x45 if needed
        result = BUTPOW;
        break;
      case 0x46: // edit 0x46 if needed
        result = BUTVOLP;
        break;
      case 0x47: // edit 0x47 if needed
        result = BUTFUNCSTOP;
        break;
      case 0x44: // edit 0x44 if needed
        result = BUTREWIND;
        break;
      case 0x40: // edit 0x40 if needed
        result = BUTPAUSE;
        break;
      case 0x43: // edit 0x43 if needed
        result = BUTFASTFORWARD;
        break;
      case 0x7: // edit 0x7 if needed
        result = BUTDOWN;
        break;
      case 0x15: // edit 0x15 if needed
        result = BUTVOLM;
        break;
      case 0x9: // edit 0x9 if needed
        result = BUTUP;
        break;
      case 0xD: // edit 0xD if needed
        result = BUTSTS;
        break;
      case 0x19: // edit 0x19 if needed
        result = BUTEQ;
        break;
      case 0x16: // edit 0x16 if needed
        result = BUT0;
        break;
      case 0xC: // edit 0xC if needed
        result = BUT1;
        break;
      case 0x18: // edit 0x18 if needed
        result = BUT2;
        break;
      case 0x5E: // edit 0x5E if needed
        result = BUT3;
        break;
      case 0x8: // edit 0x8 if needed
        result = BUT4;
        break;
      case 0x1C: // edit 0x1C if needed
        result = BUT5;
        break;
      case 0x5A: // edit 0x5A if needed
        result = BUT6;
        break;
      case 0x42: // edit 0x42, if needed
        result = BUT7;
        break;
      case 0x52: // edit 0x52 if needed
        result = BUT8;
        break;
      case 0x4A: // edit 0x4A if needed
        result = BUT9;
        break;
// add more case statements if you want to add more buttons. Also add their respective names to the remote_button
      default:
        result = BUTTONUNKNOWN;
        Serial.println(val, HEX);
        break;
      }
    return result;
  }

To check if everything works, try the following if block:

if (IrReceiver.decode())
  {
   byte recieved = IrReceiver.decodedIRData.command;
   remote_button_t button_pressed = decode(recieved);
   if(button_pressed != BUTTONHELD){
      Serial.println(button_pressed);
    }
   IrReceiver.resume();
  }

If all goes well, clicking the 0 button should result in 0 being printed, and pushing 1 should result in 1 being printed and so on.

Congratulations on getting past the hardest step!

Tying It All Together: a New Beginning

Copy of MISA 7-Segment 4-Digit LED Display (2).png

With our circuit, and the following code we can make a simple stopwatch (you'll needed to modify the decode function for your remote). Congratulations! One big issue though, the code is really finnicky. Now its up to you try to make it better. We only used the pause, number, power, eq and st/rept buttons. There are many more buttons that you can add functionality for! For example, the volume up and volume down button can change the volume of the buzzer, or you can modify the code to play a song when the timer is up. Or, you can make it an alarm clock/stop watch using the function button to alternate between the two. The possibilities are endless! Hopefully you enjoyed this journey, and if you have any questions, please feel free to ask questions.

Downloads