element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Project14
  • Challenges & Projects
  • More
Project14
Blog 7-segments project | Mission: Impossible | Geocaching Cache
  • Blog
  • Forum
  • Documents
  • Theme Suggestions
  • Polls
  • Members
  • More
  • Cancel
  • New
Join Project14 to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: feiticeir0
  • Date Created: 17 Mar 2022 1:00 PM Date Created
  • Views 3518 views
  • Likes 15 likes
  • Comments 2 comments
  • project14 7-segments display
  • 7segmentdiplaysch
  • 7segmentdisplaysch
  • project14
  • project 14
  • arduino
  • 7-segments display
  • 7-segments
Related
Recommended

7-segments project | Mission: Impossible | Geocaching Cache

feiticeir0
feiticeir0
17 Mar 2022
7-segments project | Mission: Impossible | Geocaching Cache

Mission_Impossible

Hello all ! Hope everyone is safe.

This is my entry on the Monthly (March 2022) Element14's Project14's - 7-Segments .

Geocaching Logo Geogentoo Logo

I've been doing Geocaching a long time. I just love discovering new places, the Nature and solving crazy puzzles. Geocaching can be all that . But, there's another side to it: instead solving other one's caches, create your own, give them a theme, a twist and watch (read) the Geocachers reactions. Since I was a litle, I loved treasure hunts .

I'm from the 80s, and movies like The Goonies just filled one's imagination. Who didn't want to find a pirate's treasure ? Or just like Indiana Jones. Not for the whip, but for the clues, the puzzles, the story.

My project is a cache that I've started to develop and build - but it isn't yet in the Nature to be found.  I called it Mission: Impossible

The cache

We all know the Mission Impossible movies. For those older (not my time), there was also a TV series in '66 and a TV Series in '88.

On the movies (and the series, but I'm going to concentrate on the movies) they have always a mission, that they need to complete in an impossible time frame and solve any kind of puzzles.

One day, on my email, I received an email from Instructables, with some projects. One of the projects was "The Christmas Box".  I found the idea interesting. A multitude of switches, wired in series. To open the box, you need to turn them on, sequentially.

In this case, the first switch is wired to the Arduino 5v PIN. The current is traveling along the switches (while turning them on), until the last one. This last one, the voltage is read in an analog PIN. If the value is not what's expected, the solenoid - that's closing the box - won't trigger to open the lid.

To make this a really fun cache, I've decided to up the ante.

  • I've placed some LEDs along the switches. It will be an indication for the Geocacher - when switching the switch, if the LED turns ON, they're on the right track .
  • Put a timer - with two single 7-segments display (It was what I had at the time). They need to light all the LEDs - following a path (more on this later) - before the time runs out.

Hardware

For this, we'll going to need

  • Arduino Micro (or one you like)
  • 15x miniature toggle switches ON-OFF-ON (three positions is more fun)
  • 1x miniature toggle switch ON-OFF (to turn the cache on or off)
  • 15x round LED 3-6v 6mm
  • 1x 7-segment dual display (because I didn't a double, used two singles - more complicated)
  • 1x 5v solenoid
  • 1x 9v battery adapter

Schematics

Here's all the wiring

image

The LEds in the schematic are only 3, but just add all the remaining 12 before the last one.

I know it may seem a bit daunting, but it's really not.

Circuit

Here's the start of the wiring

image

image

image

The first switch gets 5v from the Arduino. The middle PIN of the switches is always going to be connected to the next switch. Next, you make a choice. Either you solder it to the top PIN or the bottom one. This will make the switch activate by pushing the switch to top or bottom. They are 3 positions switches. triple the fun ! :)

To make the LED light turn on when putting the switch on the correct position (top or bottom, according to the PIN in which we solder the wire), just wire the positive wire in the middle PIN of the switch. The current will come from it when putting the switch on the correct position. The ground wire to the ground. You keep doing this until the final one.

One thing I've done (and you can see from the black lines in the box, next to the switches) was to create a path. If it was just flipping switches in sequence it wouldn't be as fun.

If you know Geocaching, you can - and should - give a hint to solve the cache.  Since I've added a timer, it would take some tries before they could solve the cache in under 40s. It's possible, because the LEDs would indicate that the switch is on, but let's not be too harsh. I want the people to have fun.

On the Geocaching page of the cache (to be updated when cache is published), there's this image:

image

Using the image as an hint, they will understand the order to flip the switches.

7-Segments display

image

The 7-Segments display can be of two types - common Anode or common Cathode.  Mine are common Anode, meaning all the anodes are connected to VCC and the individual segments are turned on and off by switching power to the cathodes. If it's low, then the segment is turn off and vice-versa.

Here's an excellent learning tutorial on the wiring and the types of 7-segment displays. You just need to know yours.

https://www.circuitbasics.com/arduino-7-segment-display-tutorial/

Basically, each segment of the 7-segments display (single ones. This changes for double or quadruple digits) has a pin that needs to be connected to the Arduino.  Since I'm using two single digits, way more wiring needed and the code it's a bit more complicated.

Each segment is labeled from A to G.  Each segment (at least for these 7-segments display) has a PIN to connect to the Arduino. For mine, change - to + .  (images from Circuit Basics).

imageimage

To know what PINs to connect to Arduino, check the datasheet.

Code

The code is very straightforward, being the code for the 7-segments the more "complicated" stuff, because I had to use two single digit to make one double digit.

#include "SevSeg.h"

#define readVoltagePIN A1
#define solenoidPIN A2

//#define DEBUG 1
#define DEBUG 0

/*
 * Defined those here, so we can make an animation
 * when cache is openned and show and hide where they 
 * get at
 * ie: 11s to end, so 11 wil show and hide
 */
static int i,j = 0;

SevSeg sevseg_1;
SevSeg sevseg_2;

/* declared global so it can be used in another function */
byte segmentPins_1[] = {0, 1, 2, 3, 4, 5, 6};
byte segmentPins_2[] = {7, 8, 9, 10, 11, 12, 13};

void setup() {
  // put your setup code here, to run once:
  byte numDigits = 1;
  byte digitPins[] = {};
  /* byte segmentPins[] = {A, B, C, D, E, F, G} */
  //byte segmentPins_1[] = {0, 1, 2, 3, 4, 5, 6};
  //byte segmentPins_2[] = {7, 8, 9, 10, 11, 12, 13};
  bool resistorsOnSegments = true;

  byte hardwareConfig = COMMON_ANODE;
  sevseg_1.begin(hardwareConfig, numDigits, digitPins, segmentPins_1, resistorsOnSegments);
  sevseg_1.setBrightness(90);

  sevseg_2.begin(hardwareConfig, numDigits, digitPins, segmentPins_2, resistorsOnSegments);
  sevseg_2.setBrightness(90);

  //pins to open cache and check voltage
  pinMode (readVoltagePIN, INPUT);
  pinMode (solenoidPIN, OUTPUT);
  digitalWrite (solenoidPIN, LOW);

  //because we just need this to run once, everything is in setup
  runCache();
  //display animation
  animateDisplay (i, j);
}

/*
 * animate the numbers like in the movies
 */
void animateDisplay (int i, int j) {
  while (true) {
    sevseg_1.setNumber (i);
    sevseg_1.refreshDisplay();
    sevseg_2.setNumber (j);
    sevseg_2.refreshDisplay();
    delay(1000);
    for (int i = 0; i < 7; i++) {
      digitalWrite (segmentPins_1[i],HIGH);
      digitalWrite (segmentPins_2[i],HIGH);
    }
    delay(1000);
  }
}

/*
 * Funcao para ler o pin analogico para
 * verificar se ja acenderam todos os
 * interruptores
 */
int openCache() {
  int vt = analogRead(readVoltagePIN);
  if (DEBUG) {
    Serial.println(vt);
  }
  /*
   * 900 is the minimum value read
   */
  if (vt >= 900) {
    //if we're here, it's openned and we can stop the clock
    digitalWrite (solenoidPIN, HIGH);
    if (DEBUG) {
      Serial.println("Open");
    }
    return 1;
  }
  else {
    digitalWrite (solenoidPIN, LOW);
    return 0;
  }
}

/**
 * Main function to run the cache
 * It goes from 40s to 0s and during that time,
 * will try and see if the there's voltage on A1
 */
void runCache() {
  delay(1000);
  for (i = 3; i >= 0 ; i--) {
    sevseg_1.setNumber(i);
    for (j = 9; j >= 0; j--) {
      int timer = 1;
      sevseg_2.setNumber(j);
      sevseg_2.refreshDisplay();
      sevseg_1.refreshDisplay();
      /*
       * we're testing this here, so the function to open the solenoid
       * won't have to open it only after 1s - this could be what makes
       * they open or not the cache.
       * And we're at 100ms, so 10 times * 100ms is 1s :) 
       */
      while (timer <= 10) {
        if (openCache()) {
          if (DEBUG) {
            Serial.begin("Aberto...");
          }
          return;
        }
        delay (100);
        //Serial.println(timer);
        timer += 1;
      }
    }
  }
}


void loop() {
  //loop is empty
}

We start by including the SevSeg library that I'm going to use. You can find it in github and you can install it the same way you install libraries in Arduino - using the library manager.

This library supports common anode or cathode and it's easy to work with.

We define the PINs for the Solenoid and the Analog PIN to read the voltage

#include "SevSeg.h"

#define readVoltagePIN A1
#define solenoidPIN A2

Next, we define some variables to create a nifty animations

/*
 * Defined those here, so we can make an animation
 * when cache is openned and show and hide where they
 * get at
 * ie: 11s to end, so 11 wil show and hide
 */
static int i,j = 0;

We declare two variables, one for each display, of the type SevSeg.

Then we define what pins are connected to which display, by declaring two arrays

SevSeg sevseg_1;
SevSeg sevseg_2;

/* declared global so it can be used in another function */
byte segmentPins_1[] = {0, 1, 2, 3, 4, 5, 6};
byte segmentPins_2[] = {7, 8, 9, 10, 11, 12, 13};

The setup function

The code for the cache will run all from the setup function. We don't need a loop function. More on this later.

Next, are variables that will define the library behavior and setup


  byte numDigits = 1;
  byte digitPins[] = {};
  /* byte segmentPins[] = {A, B, C, D, E, F, G} */
  bool resistorsOnSegments = true;

  byte hardwareConfig = COMMON_ANODE;
  sevseg_1.begin(hardwareConfig, numDigits, digitPins, segmentPins_1, resistorsOnSegments);
  sevseg_1.setBrightness(90);

  sevseg_2.begin(hardwareConfig, numDigits, digitPins, segmentPins_2, resistorsOnSegments);
  sevseg_2.setBrightness(90);

numDigits defines how many digits our display has. In my case, just the one. If I were to use a dual-digit display, here would be 2 or 4 for  a four-digit display.

digitPins array would define to what Arduino PINs the digits wold be connected. This is very dependent on the hardware you have. Since I'm using 1 digit display, this is empty (it needs to be defined).

Next, would the segmentPins (I've declared them above, because need them also elsewhere). This is an array that declares what segments are connected to what Arduino PINs. 7-segments display - get it ?

Read more here. Excellent tutorial and learning

resistorsOnSegments refers to if resistors are connected to the segments or digits.

hardwareConfig referes to if they are common Anode or Cathode.

There are more variables to define (i.e: leading zeros, etc..) but I don't need them, so, not declaring them. Read the library documentation - the Github page - for more information.

Next, we initialize both displays, with all the variables defined and set the brightness.

sevseg_1.begin(hardwareConfig, numDigits, digitPins, segmentPins_1, resistorsOnSegments);
sevseg_1.setBrightness(90);

sevseg_2.begin(hardwareConfig, numDigits, digitPins, segmentPins_2, resistorsOnSegments);
sevseg_2.setBrightness(90);

We then set the PIN mode for the Solenoid and the Analog for the voltage reading.  I've set the solenoidPin to low, just in case - we don't want the cache to be open when the Geocacher starts.

//pins to open cache and check voltage
pinMode (readVoltagePIN, INPUT);
pinMode (solenoidPIN, OUTPUT);
digitalWrite (solenoidPIN, LOW);

Next, we call a function to start the cache - ie, countdown timer - and next, an animation.

  //because we just need this to run once, everything is in setup
  runCache();
  //display animation
  animateDisplay (i, j);

This is way we just need the setup function. The runCache() function only exits when the timer gets to 0. If the Geocacher manages to flip all the switches in time, it signals the solenoid to open. If not, it does nothing.  If it wants to try again, just turn the cache off and on again.

runCache function

This is the function that controls everything.

void runCache() {
  delay(1000);
  for (i = 3; i >= 0 ; i--) {
    sevseg_1.setNumber(i);
    for (j = 9; j >= 0; j--) {
      int timer = 1;
      sevseg_2.setNumber(j);
      sevseg_2.refreshDisplay();
      sevseg_1.refreshDisplay();
      /*
       * we're testing this here, so the function to open the solenoid
       * won't have to open it only after 1s - this could be what makes
       * they open or not the cache.
       * And we're at 100ms, so 10 times * 100ms is 1s :)
       */
      while (timer <= 10) {
        if (openCache()) {
          if (DEBUG) {
            Serial.begin("Aberto...");
          }
          return;
        }
        delay (100);
        //Serial.println(timer);
        timer += 1;
      }
    }
  }
}

It's just two for loop functions - one controls the dozens (from 3 to 0) and the other the ones (9 to 0).

Because of the refresh (again, two single digit displays), between the for loop for the dozens and the for loop for the ones, we display the dozens, using the SevSeg function setNumber .

On the second loop, we display the ones and refresh both displays.

Inside this for loop, we set a timer. This timer is here so that the cache opens immediately if the voltage at the PIN is high enough. If we don't set this here, this was only checked after each second. 

This could work great - unless there's just one second left on the timer . Like in the movies, they all defuse the bomb in the last second - and the timer would end and not cache would open.

The delays, will time 1s for the ones and 1s for the dozens.

In this cache, there's also a checking on to open the cache

if (openCache()) {

This will check another function

openCache function

This function checks the voltage on the analog Pin (The ADC circuit) and reads the value. After some testing, 900 is the minimum value read when all the switches are flipped correctly. 

If we get lower, then it means that no voltage is reaching the PIN, hence the switches are not all flipped correctly.

NOTE: This was my way. I'm sure that could be other ways, or this value may be dependent on the battery voltage being full or almost empty. This uses a 9v battery.

If the value is above 900, then, we turn the SOLENOID PIN to high and it retracts it, opening the cache.

Back to the runCache.

If openCache returns 1 - meaning it's opened, we exit the runCache loop() - and back to the setup function. Remember - this function was called from there.

If openCache returns 0, we keep going in the openCache loop until the timer runs out (but the cache never opens).

After exiting the runCache function, we show the animateDisplay function.

animateDisplay function

This function takes 2 arguments - i and j . This are the variables that countdown in the runCache function.

If we exit the runCache function with still time left, i and j will be the time left : i is dozens and j is ones.

If we left the time run out, both will be 0.

In a infinite loop, we display i and j on the 7-digits display. Delay 1s.

After that, we put all the segment PINs on HIGH, making them turn off.  Wait 1s and display the digits again...

Here's a video of the cache working

You don't have permission to edit metadata of this video.
Edit media
x
image
Upload Preview
image

NOTE: Here's the cache page. It's not yet published, you'll received an error. It's been raining and I haven't yet had time to publish it. The cache page is done, but still have to place it .

image

References

https://create.arduino.cc/projecthub/KVLakshmiSri/00-to-99-on-seven-segment-displays-1ca7e0

https://www.circuitbasics.com/arduino-7-segment-display-tutorial/

  • Sign in to reply
Parents
  • dubbie
    dubbie over 3 years ago

    That's a lot of switches. 

    Dubbie

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Comment
  • dubbie
    dubbie over 3 years ago

    That's a lot of switches. 

    Dubbie

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
Children
  • feiticeir0
    feiticeir0 over 3 years ago in reply to dubbie

    I've always said - more switches, more fun ! Smiley

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube