Hellp with project

I have a project due next week, but I don't know how to do it. The project consists of making a binary counter. The counter should count in the range 0 – 15, displayed on 7-segment displays. The counter should have as well two push buttons attached to it. Initially, the counter increments every 1 second. By clicking button one, the counter is decremented every 1 second. Clicking the button one further will alternate the counting between incrementing and decrementing modes. The second push button changes the delay period between each count. When clicked for the first time, it increases the delay to 2 seconds. Clicking it for the second time will increase the delay to 3 seconds. Clicking it for the third time will make the delay period 0.1 seconds. Clicking for the fourth time will increase the delay period to 0.5 seconds. Finally, clicking it for the fifth time will bring the delay period to its default value of 1 second, and so on.

Hello valerod02

Post your current sketch to see how we can help.

The state change detection tutorial will help with counting button presses. See also my state change for active low inputs tutorial.

There are lots of seven segment tutorials. Google something like "2-digit seven segment display Arduino code" Suspect the quality of any tutorial that does not use a resistor for each segment.

This is what I have until now

const uint8_t segmentsPins[] = { 9, 8, 7, 6, 5, 4, 3 }; //ABCDEFG
const int P1 = 10;
const int P2 = 11;
int buttonState = 0;
void setup() {
  // put your setup code here, to run once:
 for ( uint8_t i = 3; i < 9; i++ ) //loop over segmentsPin from 4 to 9 and set them all to output
  {
    pinMode( segmentsPins[i], OUTPUT );
  }
pinMode(P1, OUTPUT);
pinMode(P2, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

}
void counter(){
  uint8_t segmentsData[] =
  {
    //GFEDCBA
    0b0111111, // '0'
    0b0000110, // '1'
    0b1011011, // '2'
    0b1001111, // '3'
    0b1100110, // '4'
    0b1101101, // '5'
    0b1111101, // '6'
    0b0000111, // '7'
    0b1111111, // '8'
    0b1100111, // '9'
  }
buttonState = digitalRead(P1);
if (buttonState == 1){
  
}

  }
}

Show us what you have, parts, hand drawn schematic, pics, code (formatted with </>), etc. Give us everything - but realize we're NOT a "homework service".

Not bad for a start.
A few tips.
Line out your braces. You might already have one } too many.
Make compilable code. Do not write lots of code and then try to compile.
Make code that does something.
Take small steps.
Read a button and write state to Serial.
Derive a counter based button state. Write counter to Serial.
Now make your 7 segm display show a 1. Then all numbers.
Then connect the counter and the 7 segm display.
Put 7 segm display and botton counter in separate functions. It is best if each function does only one thing, not two or three.
Your function call to 7 segm display should look like.
void display(int number);
So again: take small steps. Check result of each step. Use Serial a lot.

You are completely right...
Maybe we should add then that function implementation should be like this:

void display(int number){
    Code to make show display number
}

As the function declaration is not needed with Arduino IDE and might be confusing OP.

1 Like

This is the new code I am doing. I think most of it is wrong

// 7-Segment Display
const uint8_t segmentsPins[] = {8, 7, 6, 5, 4, 3, 2}; //ABCDEFG
// Digits Display
const int D1 = 9;
const int D2 = 10;
//Push Buttons 
const int pushInDec = 11;
const int pushVel = 12;

const byte segments[7]= { a, b, c ,d ,e, f, g };
const byte digits_order[2]={ D1, D2};
const byte segmentsData[10]={ 0b0111111, 0b0000110, 0b1011011, 0b1001111, 0b1100110, 0b1101101, 0b1111101, 0b0000111, 0b1111111, 0b1100111}; //GFEDCBA

bool bPress = false;
int pushButtonCounter = 0;
int pushButtonDealy = 0;
int value = 100;

void activeDigit(int x){
digitalWrite(D1, HIGH);
digitalWrite(D2, HIGH);
switch(x){
  case 1:
  digitalWrite(D1, LOW);
  break;
  case 2:
  digitalWrite(D2, LOW);
  break;
}
}

void lightSegments(byte segmentsData) {
  for (int i = 0; i < 7; i++) {
    int bit = bitRead(byte segmentsData, i);
    digitalWrite(segments[i], bit);
  }

void setup(){
// loop over segments Pin from 2 to 8 and set them all to output
for (unit8_t i = 2;i <= 8; i++ ){
   pinMode( segmentsPins1[i], OUTPUT);
}
  pinMode(pushInDec, INPUT_PULLUP);
  pinMode(pushVel, INPUT_PULLUP);
}

void loop(){
  int counter = 0;
  pushButtonCounter = digitalRead(pushInDec)
  for(counter = 0;  counter <= 16; j++){ 
 if(pushButtonCounter == 0) {
 counter++;
 if(counter == 16){
   counter = 0;
 }
 delay(value);
 }
for(counter = 0;  counter >= 15; j++){ 
 if(pushButtonCounter == 1) {
 counter--;
 delay(value);
 }
}

Some simple button tricks, since you cant let go fast enough to register only once

bool pushInDec= 11;         //button one
bool pushVel= 12;              //button two
bool mode=0;                   //increment/decrement
int period=0;                      //period selector
int button1,button2          //counters
int value;                             //delay time
....



if (pushInDec == 1)button1++;      //button action counter, can be done better with millis
else button1=0;                                    //reset counter if not pressed

if (pushVel == 1)button2++;
else button2=0;

if (button1>100) button1=0;         //optional to pres again automatically when held
if (button2>100) button2=0;

if (button1==1) mode=1-mode;         //execution
if (button2==1) period++;         //button1==? determines how long pressed before activation... only counts loop pases, millis would be better

if(period>5)period=0;                          //after 5 executions return to 0

if (period==0)value=1;                        //modes
if (period==1)value=2;
...

try to avoid delay whenever you can in general, look at blink without delay example as delay stops the loop, and messes with all time sensitive actions, and counters done in this way

Anyway counters done in this way increment after each loop cycle, longer the code, more time it takes, that's why its better to use internal timer, but this is very simple, and good enough if you don't delay the loop

hope I got the button names correct, thats why you add //commentary

@valerod02,

Your other topic on the same subject deleted.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

Some corrections

bool pushInDec= 11;         //button one
bool pushVel= 12;              //button two

bool variables can be exactly true or false, not 11 or 12.

Maybe you meant

const byte pushInDec = 11;
const byte pushVel = 12;

but there's more

if (pushInDec == 1)button1++;      //button action counter, can be done better with millis
else button1=0;                                    //reset counter if not pressed

if (pushVel == 1)button2++;
else button2=0;

Neither will ever be equal to 1. Perhaps you meant to throw a digitalRead() in there to get the logical value being presented at the input pin.

if (digitalRead(pushInDec) == 1) button1++; 

and so forth.

HTH

a7

I changed all my code. I was able to make the counter work but know I am having problems with the buttons, they are not working .

#include "SevSeg.h"
SevSeg sevseg;

float fast= 0;
float displayTime = 1000;
long startsNumber = 0;
long endsNumber = 15;
const int InDecButton= 12;
bool bPress = false;
const int SpeedButton= 13;

void setup() {
  // put your setup code here, to run once:
  byte numDigits = 2;
  byte digitPins[] = {2, 3};
  byte segmentPins[] = {4, 5, 6, 7, 8, 9, 10, 11};
  bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
  byte hardwareConfig = COMMON_CATHODE; // See README.md for options
  bool updateWithDelays = false; // Default 'false' is Recommended
  bool leadingZeros = true; // Use 'true' if you'd like to keep the leading zeros
  bool disableDecPoint = true; // Use 'true' if your decimal point doesn't exist or isn't connected. Then, you only need to specify 7 segmentPins[]

  sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments,
  updateWithDelays, leadingZeros, disableDecPoint);
  sevseg.setBrightness(90);

  pinMode(InDecButton,INPUT);
  pinMode(SpeedButton,INPUT);

  attachInterrupt(digitalPinToInterrupt(SpeedButton), Speed, CHANGE);
  attachInterrupt(digitalPinToInterrupt(InDecButton), UpDown, CHANGE);

}

void loop() {
  if(bPress){up();}
  else{down();}
}
void up(){
    if (startsNumber <= endsNumber) {
    for(long i = 0; i<= displayTime; i++){
      sevseg.setNumber(startsNumber,0);
      sevseg.refreshDisplay();
    }
  startsNumber++;
  if (startsNumber == 16) { // Reset to 0 after counting for 1000 seconds.
      startsNumber = 0;
    }
    sevseg.setNumber(startsNumber,0);
}
}

void down(){
    if (startsNumber <= endsNumber) {
    for(long i = 0; i<= displayTime; i++){
      sevseg.setNumber(endsNumber,0);
      sevseg.refreshDisplay();
    }
  endsNumber--;
  if (endsNumber == 0) { // Reset to 0 after counting for 1000 seconds.
      endsNumber = 15;
    }
    sevseg.setNumber(endsNumber,0);
}
}

void UpDown(){
bPress = digitalRead(InDecButton);
bPress =! bPress;
}
void Speed(){
fast= digitalRead(SpeedButton);
fast = fast + 1;
if(fast == 5){fast = 0;}
if (fast == 0){displayTime = 1000;}
else if(fast== 1){displayTime= 2000;}
else if(fast== 2){displayTime= 3000;}
else if(fast== 3){displayTime= 100;}
else if(fast== 4){displayTime= 500;}
}

fast will be 0 or 1 after the digitslRead().

fast will be 1 or 2 after adding 1 to it.

So yeah, your button is probably working just fine, but clearly you intended something different to happen…

a7

You are not using the internal pull-up resistor (INPUT_PULLUP) so you must be using an external pull-up or pull-down resistor. Which is it?

Did you want to toggle 'bPress' on each press of "InDecButton"? That would be something like:

// InDecButton CHANGE ISR
void UpDown()
{
  if (digitalRead(InDecButton) == HIGH)
    bPress = !bPress;
}

y, copied his code, those should be pin numbers, not values... :sweat_smile: , He can digital read out of the if function too, and set the variable that way I think.... I would most likely define the pins and make cases for button press, or digital read from pin in the if function like you suggested....
didn't want to write the entire piece from the get go, and those are some beginner stuff to help think in code :laughing:
the output can be done in couple of ways here too...
either trigger function with for/while loop for each mode, or in the main loop
I tend to separate everything in functions lately

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.