Not enough pins for my project

Hi, my project requires me to connect 5 buttons, 1 LED, 1 7 segment LED and 1 4 digit 7 segment LED. I do not know how I would go about connecting it. Can someone please tell me how?

Each input sw & led needs a pin. 7 seg can use 7 or 4 wires depending if you have a 7447 decoder/driver IC or are directly addressing segments. You might want an I2C 4 digit display that only needs two signals, SDA/SCL. if uno doesn’t cut it, mega has 70 io's

5 input buttons
1 led
4 lines & blank for 7 seg led
sda/scl for 4 digit led
usb 2 lines 0 & 1

I count 16 io's. UNO should work. SDA/SCL are A4 & A5, other analogs can be digitals too.
7seg

Many use modules for the 7-segment displays that have a clock and data line. Some have a I2C bus with two pins.

This Adafruit module seems to be exactly the same as the one on your picture. It uses the I2C bus. You need a library to use it. Adafruit has a tutorial for that display.

I forgot to mention that I have to use a provided 12 pins having 4 digit 7 segment like this. My apologies. And also I can only use an Atmel Uno board.

A quick and dirty way of getting more output pins is to use a shift register. There's a tutorial about it available. You can daisy chain the shift registers to get as many output pins as you need, at the expense of speed. Each chain of shift registers will only need three output pins. for the programming side, see the shiftOut() function.

Unfortunately, the assignment requirements stops me from adding any external gadgets.

A good practice to choose a board for the project
You must first decide on the modules used, calculate the number of required interfaces and pins - and only then choose the board.

In this case, the chances of a successful completion of the project are low.
What did you think when you planned the project?

I did not plan the assignment, my lecturer did.

Can you add resistors ? Because those 7-segment display require resistors.

Display: 7 lines abcdefg, 4 digits, multiplexing with SegSev library. Total of 11 pins.
Buttons: 1 pin when using a analog ladder to a single analog pin.
Extra 7-segment led. Let's add that to the others (I hope the library can do 5 displays). So 12 pins for the all the 7-segment displays.
A led: 1 pin.
Leaving pin 0 and pin 1 unused, to be able to use the Serial Monitor.

That needs 16 pins.

I can open the trickery box, and blink the led with the AREF pin (and damage the microcontroller), combine the buttons with the display lines (5 buttons, 5 displays), ignore the Serial Monitor and use only 12 pins. I think that is the minimum.

So you want us to do your homework for you?
Will you get a good mark?
Are you going to share that mark with us?

Do you not think this is cheating?

Any more hidden limitations you have not told us about?

4 Likes

Interesting assignment.

@coldnanxd

Let see if you can connect all the 7 segments, one led, and 5 push buttons switches.
So count the total pins the Arduino have , except pin 0 and pin 1.
1.. Let see ... from pin 2 to pin 13 - 12 pins. The analog pins ... can they be connected as digital pins ... YES ... 6 pins. So you have a total of 18 pins
2. You need 5 input pins ... 5 switches ... Those can be connect to the analog pins of the arduino. and one analog pin for the led.
3. The output pins ... you got from 2 to 13. 5 pins for the digits, and 7 pins for a,b,c,d,e,f,g
4. Except pin 0 and 1 are use for the Rx and Tx ... Serial Data.
5. The Hit Led can be pin 13. So one analog pin as to be use as one the digits - Coordinate 7 segments. The rest of the analog pins can be set as digital Input. The rest of the output pins will be use for - Ships Sunk, No Hits, No Shots ( the digits ) and the rest the display leds that is a, b,c,d,e,f,g ...the dots is not connected.
6. The displays have to be multiplex.

Therefore you do have enough pins for this assigment. 5 inputs, 13 outputs.

The rest you have to do "homework" ... I mean ... research how to breadboard and connect the system. Look for how to connect a push button switches, and how to connect multiple 7 segments display in a multiplex way. Check for common Cathode and common Anode type of 7 segments.

And ... the 12 pins 7 segments display you mention, I have the double dot in the middle, the one that I have are common Anode type. use a common a,b,c,d,e,f,g connection internally. Do a test connection to confirm. AND ... PLEASE put limiting resistors .... from 330 to 470 should be fine.

@Koepel

Yeah .... I forgot that that the push buttons can be use as a ladder. If I remenber ... a flash digital to analog converter. That is a good trick.

In that case, you're going to be doing a lot of multiplexing.

Use 7 digital pins as segment drivers for the LED. (8 if you want the decimal point too.)
Use 5 pins as digit selects for the 7 segment displays, and also as column drivers for a 5x1 matrix keyboard.
Use 1 pin as the row input from the keyswitch matrix.
Use 1 pin for the discrete LED.

That's 14 pins of the 13 digital I/O pins on the Arduino, but don't forget that the analog pins can also be used as digital pins. pinMode(A3,INPUT_PULLUP); is perfectly valid. That gives you another six I/O pins.

You will have to add a resistor on each of the segment output pins to limit the LED current, and another resistor in series with the discrete LED. Not having those resistors will damage the LED, the microprocessor, or both.

On the software side, you set up the segment data, then turn on ONE of the digit select lines. leave it like that for a millisecond or so, then read the switch input line. if that line is active, then the switch connected to the currently active digit line is pressed. Then disable that digit, set up the data for the next seven segment digit, and do the whole thing all over again.
Cycling through the digits fast enough will make it appear like they are all on, even though only one is on at any given time.

I usually like to set up a timer interrupt at a regular interval like 1mS. The interrupt handler reads the segment data from a buffer (one byte of buffer per digit), updates the digit line, and in this case reads the switches and reports the result in another buffer for the main program to read.

One warning. As both the display buffer and the switch result buffer are used by both the interrupt code and the main code, they must be specified with the volatile keyword to avoid problems.

Try charlieplexing, then.

Look for the details as part of your assignment.

The SevSeg library can combine two displays and use parts of it as separate digits. Here is my test sketch:

// Test if two seperated 7-segment displays can be controlled by the SevSeg library.
// The single-digit display is located on the left of the four-digit display.
//
// SevSeg library: https://github.com/DeanIsMe/SevSeg
// Using the stringWithPeriod.ino sketch as starting point:
// https://github.com/DeanIsMe/SevSeg/blob/master/examples/stringWithPeriod/stringWithPeriod.ino
//
//
// Both displays are "common anode".
//

#include <SevSeg.h>
SevSeg sevseg;

unsigned long previousMillis;
const unsigned long interval = 500;
unsigned long previousMillisFast;
const unsigned long intervalFast = 100;

void setup() 
{
  byte numDigits = 5;
  byte digitPins[] = {6, 2, 3, 4, 5};  // single display, DIG1 ... DIG4
  byte segmentPins[] = {7, 9, 11, 12, 13, 8, 10}; // a...g

  bool resistorsOnSegments = false;    // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_ANODE;  // See README.md for options
  bool updateWithDelays = false;       // Default. Recommended
  bool leadingZeros = false;           // Use 'true' if you'd like to keep the leading zeros
  bool noDecimalPoint = true;          // No decimal point in this project
  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, noDecimalPoint);
  sevseg.setBrightness(100);           // 100 is default, 0...200
}

void loop() 
{
  unsigned long currentMillis = millis();
  bool update = false;                 // set default

  static int xr;
  int xm;
  static int xlfast;
  int xl;
  static int y;

  if( currentMillis - previousMillis >= interval)
  {
    previousMillis = currentMillis;
  
    // Two digits on the right, "xr"
    // Count up
    xr++;
    if( xr > 99)
      xr = 0;
    update = true;


    // One digit on the left, "xl"
    // Count up slow
    xlfast++;
    xl = xlfast / 4;
    if( xl > 9)
    {
      xlfast = 0;
      xl = 0;
    }
    update = true;


    // One digit on its own, "y"
    // count up and down
    static int inc = 1;
    y += inc;
    if( y == 9)
      inc = -1;
    if( y == 0)
      inc = +1;
    update = true;
  }


  if( currentMillis - previousMillisFast >= intervalFast)
  {
    previousMillisFast = currentMillis;

    // One digit in the middle, "xm"
    // set to random
    xm = random(0,10);
    update = true;
  }


  // Update the numbers if needed.
  if( update)
  {
    char buffer[10];
    snprintf( buffer, sizeof(buffer), "%1.1d%1.1d%1.1d%02.2d", y, xl, xm, xr);
    sevseg.setChars( buffer);
    update = false;
  }

  sevseg.refreshDisplay();             // This function keeps the displays going
}

The sketch in Wokwi:

Well, if it can't be done at the learning level the class is at, the marks will be bell curved and you will get a passing grade for a good try.

Sometimes, I've overlooked "what the assignment expected me to do" and got sidetracked. A huge roadblock probably won't be put in front of you, except to trigger the easy solution that was hinted at in some other part of the course materials.

So think hard about what was discussed in lecture, or book. The assignment is designed to test what you learned there, not in other places.

Example, if Charlieplexing was never mentioned, you probably shouldn't get involved in that unless you can really present it brilliantly. People who mark, hate to spend hours understanding arcane solutions even if they are good ones.

This temperature display with a 328p works by multiplexing the display as you mentioned. The red arrow points at the ir sensor.

The seven segments are on the top and the common cathode controls are on the bottom, one switch is degree/centigrade display and the other is the micro reset...

It read the temperature from one of the ir temperature sensors...


I set the scan up with the default watchdog interrupt controlling it.

:smiley_cat:

1 Like

You must use at least some resistors as has been pointed out. For good display brightness you'll need 5 transistors as well.

Are you allowed to use libraries or must you code the display handling code yourself?

First you have to find datasheets for the two displays. Hopefully these have the same configuration (common anode or common cathode) or the coding will be more complex. From those you can calculate the resistor values and the transistor types (if used) . Then you can devise a multiplexing strategy.

Can any of the buttons be pressed simultaneously?
Are the decimal points used on the displays?

Or one single analogue input pin.