Some more newb questions (shift registers)

Hi everyone,

Thanks in advance for having a look! Let me start off by telling you guys I'm a total newb at this sort of stuff, but I'm really getting into it! I'm not alone in this and luckily I have some people around me that are able to explain electronics to me. Not after blowing up my first LED of course. :slight_smile:

For my first Arduino project I was going to create something simple, at least, thats the plan. I have a 4 digit 7 segment display to which I want to write a certain input number using a keypad. After the input, the Arduino will light up another LED that amount of times following a certain loop:

  • Light up LED for a few ms
  • Minus 1 number on the display
  • (This will be later) wait for confirmation signal
  • Start from top

I'm starting it simple with just the 7segment display and a button which adds 1 to the amount displayed on the display. I have no idea how to make it count down after different button press though. Also, when I'm going to want and use the keypad, I'm not going to have enough IO. Does anyone have a comprehensive story on how I could handle this with shift registers?

This is my working code for now. I'm currently fiddling with it with different things I read but so far it isn't working and a good explanation from someone would help a lot I guess! :slight_smile:

#include "SevSeg.h"

const int COMMON_CATHODE = 0;
const int buttonPin01 = 1;

SevSeg SevSeg01;
int displayType = COMMON_CATHODE;
int numberOfDigits = 4;
int deciSecond = 0;
boolean lastButton = HIGH;
boolean currentButton = HIGH;
long timer = millis();

int inputNumber = 0;

void setup() {
  SevSeg01.Begin(displayType , numberOfDigits, 3, 4, 5, 6, 7, 8, 9, 10 , 11, 12 , 13);
  SevSeg01.Brightness(90);
    pinMode(buttonPin01, INPUT); 
}

boolean debounce(boolean last)
{
  boolean current = digitalRead(buttonPin01);
  if (last != current)
  {
    delay(75);
    current = digitalRead(buttonPin01);
  }
  return current;
}

void loop() {
  SevSeg01.PrintOutput();
  currentButton = debounce(lastButton);
  if (lastButton == HIGH && currentButton == LOW)
  {
    inputNumber++;
  if (inputNumber >= 10000) {
      inputNumber = 0;
    }
  }
  SevSeg01.NewNum(inputNumber, 0); 
  
  if (millis() - timer >= 100)
  {
    timer = millis();
    deciSecond++;
  }
  delay(5);
}

Thanks! :slight_smile:

**EDIT: Ok, so I've been busy. The counting down isn't really and issue apparently. I made a 2nd button for subtracting 1 per push. My other questions still stand though! And oh, I tried using the IO port 0 but it wouldn't let me upload. Now I'm using A5 instead.[/u]
[u]
```[/u]
[u]
#include "SevSeg.h"

const int COMMON_CATHODE = 0;
const int buttonPin00 = A5;
const int buttonPin01 = 1;

SevSeg SevSeg01;
int displayType = COMMON_CATHODE;
int numberOfDigits = 4;
int deciSecond = 0;
boolean lastButton = HIGH;
boolean currentButton = HIGH;
long timer = millis();

int inputNumber = 0;

void setup() {
 SevSeg01.Begin(displayType , numberOfDigits, 3, 4, 5, 6, 7, 8, 9, 10 , 11, 12 , 13);
 SevSeg01.Brightness(90);
 pinMode(buttonPin01, INPUT);
 pinMode(buttonPin00, INPUT);
}

boolean debounce00(boolean last)
{
 boolean current = digitalRead(buttonPin00);
 if (last != current)
 {
   delay(75);
   current = digitalRead(buttonPin00);
 }
 return current;
}

boolean debounce01(boolean last)
{
 boolean current = digitalRead(buttonPin01);
 if (last != current)
 {
   delay(75);
   current = digitalRead(buttonPin01);
 }
 return current;
}

void loop() {
 SevSeg01.PrintOutput();
 currentButton = debounce00(lastButton);
 if (lastButton == HIGH && currentButton == LOW)
 {
   inputNumber--;
   if (inputNumber >= 10000) {
     inputNumber = 0;
   }
 }
 currentButton = debounce01(lastButton);
 if (lastButton == HIGH && currentButton == LOW)
 {
   inputNumber++;
   if (inputNumber >= 10000) {
     inputNumber = 0;
   }
 }
 SevSeg01.NewNum(inputNumber, 0);

if (millis() - timer >= 100)
 {
   timer = millis();
   deciSecond++;
 }
 delay(5);
}[/u]
[u]
```**[/u]

There is a keypad section, in this section of the playground HERE, take a look at the examples.

HazardsMind:
There is a keypad section, in this section of the playground HERE, take a look at the examples.

Thanks! Already found out about that one. :slight_smile:

So I've been reading about shift registers and watching a few youtubes on it. I think I grasp the concept but I see a lot of work ahead of me. Any knowledge on a library which supports shift registers for 4dig7seg display? Or am I stuck having to define all the numbers myself? (Or am I thinking wrong here and it's possible to use sevseg.h for this purpose?)

Also, I have to put my buttonpress from HIGH to LOW. Isn't it supposed to be the way around? Did I miss-wire something? It works now but I feel it shouldn't.

Any knowledge on a library which supports shift registers for 4dig7seg display?

Im not sure on that, I know there are plenty of libraries that work with 7 segment displays, but I am not sure if there are any that just work shift registers.

Take a look at this link

SPI and shift registers go together quite nicely.

" 4dig7seg display" usually indicates multiplexing is required.
Is the display common cathode? MAX7219 can drive that, very straightforward with just 3 control pins needed.
It can also drive common anode, but you have to use No Decode mode and create font definitions.

HazardsMind:
Im not sure on that, I know there are plenty of libraries that work with 7 segment displays, but I am not sure if there are any that just work shift registers.

Take a look at this link
http://www.instructables.com/id/4-Digit-7-Segment-LED-Display-Arduino/

Thanks, that's basically how I've set it up now, doesn't involve a shift register this way but uses up a lot of IO pins. I'm trying to avoid that using a shift register because it seems like a good place to start with using those. :slight_smile:

LarryD:
SPI and shift registers go together quite nicely.

Could you elaborate? (while I'm reading this: Serial Peripheral Interface - Wikipedia)

CrossRoads:
" 4dig7seg display" usually indicates multiplexing is required.
Is the display common cathode? MAX7219 can drive that, very straightforward with just 3 control pins needed.
It can also drive common anode, but you have to use No Decode mode and create font definitions.

I'm using a common cathode right now. It is multiplexed and from what I can find this is a pretty common display (at least all the pinouts look the same for this 12 pin version). MAX7219 is a specific type of LED display driver I've found. Is this totally different than a shift register or the same thing meant for LED's? I was going to use 74HC595N but I read now this might not be a good idea (not meant to drive LED's), though I could use it if I use some transistors and an alternate powersource? Please tell me if I'm totally wrong on this.

I hope I don't come across too stupid, it's all just very new and there is A LOT to learn! :smiley:

MAX7219 is 8 shift registers and multiplexing control circuit all in one package.

After setting up 5 control registers in setup(), merely send it the pattern/you want displayed on a digit.
It has some fonts built in - 0-9, H-E-L-P, others you cam make up using NoDecode mode.
To update a specific display:

digitalWrite (ssPin, LOW);
SPI.transfer (address); // 1 to 8 for 8 displays
SPI.transfer (number_to_display);
digitalWrite (ssPin, HIGH);

Dirt simple. Can do it in a loop using arrays:

for (x=0; x<8; x=x+1){
digitalWrite (ssPin, LOW);
SPI.transfer (x+1); // results on 1 to 8 for 8 displays
SPI.transfer (number_to_display[x]); // arrays start at 0, so 0 to 7
digitalWrite (ssPin, HIGH);
}

MAX7219 is the way to go then. Did not know these things existed. So if I get this right; with this IC I wouldn't have to worry about my cathodes being pulled down (up?) by a resistor, just plug it all on the IC? Could you take it one tiny step back and please also elaborate on the control registers? I feel like I'm this close to understanding this but not quite there yet. :slight_smile: