/*

##########################################################
||                                                      ||
|| Title: Binary Counter with a 74HC595 Shift Register  ||
||                     Name: GC1CEO                     ||
||                   Date: 09/17/2024                   ||
||                     Attribution:                     ||
||          Based on shiftOutCode, Hello World          ||
||       by Carlyn Maw,Tom Igoe, David A. Mellis        ||
||         Date: 10/25/2006 Modified: 3/23/2010         ||
||                                                      ||
||                     Description:                     ||
||This counts from 0 to 255 on a 75HC595 Shift Register ||
||         and outputs the results on 8 LEDs.           ||
||  It also has a potentiometer for speed control and   ||
||      a button that can pause/unpause the count.      ||
||                                                      ||
##########################################################

*/
//Pin connected to ST_CP (Storage Clock / Latch) of 74HC595
int latchPin = 8;
//Pin connected to SH_CP (Shift Clock) of 74HC595
int clockPin = 12;
////Pin connected to DS / SER (Data/Serial Input) of 74HC595
int dataPin = 11;
////Pin connected to inverted MR / SRCLR (Master Reset / Serial Register Clear) of 74HC595
int resetPin = 10;
////Pin connected to inverted OE (Output Enable) of 74HC595
int oePin = 9;
// Pin connected to push button (pause count)
int buttonPin = 2;

// Pin connected to potentimeter (delay between cycles control)
int potPin = A0;



// initial state of button and last button state
bool lastButtonState = 0;
bool buttonState = 0;

// delay between each number (in ms)
int delayTime = 500;


// Analog Read from potPin and Output mapping inputValue
int inputValue = 0;
int outputValue = 0;

void setup() {
Serial.begin(9600);
//set pins to output so you can control the shift register and setting button and pot pins to INPUT
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(resetPin, OUTPUT);
pinMode(oePin, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode(potPin,INPUT);

// Setting reset to HIGH to stop reset and setting output enable to LOW to always enable output
digitalWrite(resetPin, HIGH);
digitalWrite(oePin, LOW);

// Cleaning up serial monitor and announcing program has initalized and going to loop
for(int a = 0; a < 25; a++) {
  Serial.println("");

}
}
void loop() {
// count from 0 to 255 and display the number
// on the LEDs
Serial.print("Counting from 0 to 255!");
Serial.println();

// for loop to count from 0 to 255
for (int numberToDisplay = 0; numberToDisplay < 255; numberToDisplay++) {

// Getting pot value from analog read, mapping it to between 50 ms and 1000 ms and changing the delay time to that value
inputValue = analogRead(potPin);
outputValue = map(inputValue, 0, 1023, 50,1000);
delayTime = outputValue;


// set the button state to the current buttonPin's digital state at top of each cycle of the for loop

buttonState = digitalRead(buttonPin);




// if the button state is pressed then announce pause and toggle last button state
if((buttonState == HIGH)) {
   Serial.println();
   Serial.print("PAUSED!");
   Serial.println();
  lastButtonState = !lastButtonState;


// As long as last button state is on then stay paused
  while (lastButtonState == 1)
  {
   
   delay(1000);
   buttonState = digitalRead(buttonPin);


// if the button is pressed again, toggle last button state, announce unpausing and break from while loop
   if(buttonState == HIGH)
   {
    lastButtonState = !lastButtonState;
    Serial.println();
   Serial.print("UNPAUSED!");
   Serial.println();
    break;
   }

   
  } }
  


  
// set the latch pin to low so LEDs dont change during shift

digitalWrite(latchPin, LOW);
// shift out the bits:
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);
//take the latch pin high so the LEDs will light up:
digitalWrite(latchPin, HIGH);
//print the number to serial

Serial.print(String(numberToDisplay) + " ");

// new line every 5 counts (and after the initial 0)
if(numberToDisplay % 5 == 0) { Serial.println("");}


// set the button state to the last button state
lastButtonState = buttonState;

// pause before next value
delay(delayTime);
}

// Announcement that count has finished and is now restarting

Serial.print("Count finished! Restarting!");
Serial.println();
}
$abcdeabcde151015202530354045505560fghijfghij
74HC595