74hc595, using it for input, How can I convert an Int Array To Binary?

I'm trying out a different use of a 74hc595. My idea was to use two buttons inputs for 1 and 0 and a third pin that would write all 0's and make use of the QH pin to input the data entered into the Arduino. This is the first stage of what I hope will be a binary calculator.

My problem right now is how to store the input from the 595 in a way that will allow math to be performed. The idea is that in the future I will have two 595's and a matrix of buttons to allow AND, OR, XOR, ADD, SUB, etc functions to be performed on the two values.

I've tried atoi and several other methods to make my array into a byte but I'm stuck and could use some help. I'm not even sure storing it in an array makes sense. This is my first project and post to the forum so I hope I haven't made any mistakes.

Here is my current breadboard:


Imgur

Button functions from left to right:

  • Shiftout a 0 bit[1]
  • Shiftout a 1 bit[1]
  • Shiftout 8x 0 bit and use QH pin to read value entered by user into the arduino[1]
// // ****************************************************
// binary input with 2 buttons and a third read button
// with 1 x 74HC595 shift register
// ****************************************************
// by Philip Prescott-Decie
//*****************************************************

// Arduino to IC 74HC595
int latchPin = 12;  						//IC Pin 12 latch-signal
int clockPin = 11;		 					//IC Pin 11 serial CLK
int dataPin = 13;	 						//IC Pin 13 serial DATA input
int input = 3;								//IC Pin 3 Input QH (output pin normally sent to second register is used to read in data)
int button0 = 2;			  			  	// pin to connect [0] button
int button1 = 4;			  			  	// pin to connect [1] button
int button2 = 5;			  			  	// pin to connect [PRINTOUT] button
int buttonState0 = 0;         				// current state of the [1] button
int lastButtonState0 = 0;     				// previous state of the [1] button
int buttonState1 = 0;         				// current state of the [0] button
int lastButtonState1 = 0;     				// previous state of the [0] button
int buttonState2 = 0;         				// current state of the [0] button
int lastButtonState2 = 0;     				// previous state of the [0] button
byte pinState = 0b00000000;					// store binary
int binary[] = {0, 0, 0, 0, 0, 0, 0, 0};	// Array used to store Data from IC - Perhaps possible to change to byte?

void setup()
{
    // Handshake-Connections 
    pinMode(latchPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(button0, INPUT);
	pinMode(button1, INPUT);
	pinMode(button2, INPUT);
    Serial.begin(9200);
}

void loop()
{
    // read the pushbutton input pin:
	buttonState0 = digitalRead(button0);
	buttonState1 = digitalRead(button1);
	buttonState2 = digitalRead(button2);
	
    if (buttonState0 != lastButtonState0) {
		// check for state change
		if (buttonState0 == HIGH) {
			// if the current state is HIGH then the button went from off to on:
			Serial.println("Button 0 on");	  
			digitalWrite(latchPin, LOW); //ground latchPin and hold low for as long as you are transmitting   
			digitalWrite(clockPin, LOW);
			digitalWrite(dataPin, LOW);  // write a zero
			digitalWrite(clockPin, HIGH);
			digitalWrite(latchPin, HIGH); //return the latch pin high to signal chip that it
			delay(250); //add a delay to avoid double entries
		}
	} else {
		if (buttonState1 != lastButtonState1) {
			// check for state change
			if (buttonState1 == HIGH) {
				// if the current state is HIGH then the button went from off to on:
				Serial.println("Button 1 on");	  
				digitalWrite(latchPin, LOW); //ground latchPin and hold low for as long as you are transmitting   
				digitalWrite(clockPin, LOW);
				digitalWrite(dataPin, HIGH);  // write a one
				digitalWrite(clockPin, HIGH);
				digitalWrite(latchPin, HIGH); //return the latch pin high to signal chip that it
				delay(250); //add a delay to avoid double entries
			}
		} else {
			if (buttonState2 != lastButtonState2) {
			// check for state change
				if (buttonState2 == HIGH) {
				// if the current state is HIGH then the button went from off to on:
					Serial.println("Button 2 on");	
					for (int i = 0; i < 8; i++){
						binary[i]=digitalRead(input);
						Serial.println(binary[i]);
						digitalWrite(latchPin, LOW); //ground latchPin and hold low for as long as you are transmitting   
						digitalWrite(clockPin, LOW);
						digitalWrite(dataPin, LOW);  // write a zero
						digitalWrite(clockPin, HIGH);
						digitalWrite(latchPin, HIGH); //return the latch pin high to signal chip that you are done transmitting
						delay(1);
					}
				}
			}
		// Delay a little bit to avoid bouncing
		delay(100);
		}
	}
}
					for (int i = 0; i < 8; i++){
						binary[i]=digitalRead(input);

The digitalRead() function is (stupidly) written to return an int, but it actually returns either HIGH or LOW (1 or 0), which would easily fit in a byte.

It is hard to imagine why you are having difficulties converting 0 or 1 to binary.

PaulS:

 for (int i = 0; i < 8; i++){

binary[i]=digitalRead(input);



The digitalRead() function is (stupidly) written to return an int, but it actually returns either HIGH or LOW (1 or 0), which would easily fit in a byte.

It is hard to imagine why you are having difficulties converting 0 or 1 to binary.

The third button shiftOut's 8 zeros into the shift register and uses its cascade output to input the 8 values entered by the user on the shift register.

In escence in the for loop you quoted, each input is one bit of a larger byte, hence why I initially used an array.

How could I write all of this input one bit at a time (in the for loop you quoted) into a byte?

=====

Usage explanation:

You press in with the two buttons the binary bit 1 or 0 that you want. So 4 presses of button1 results in 11110000 displayed on the shift register. When you press button2 it sends 8 zeros 00000000 to the shift register and reads in using the cascade output the value you entered. This may seem worthless right now but the idea is to have two such shift registers and a matrix of buttons each with a different function. This would allow a user to enter 2 values and do bitwise operations.

Found a solution to store the int array into an int with the correct value for the byte entered :

int b = binary[0] | (binary[1] << 1) | (binary[2] << 2) | (binary[3] << 3) | (binary[4] << 4) | (binary[5] << 5) | (binary[6] << 6) | (binary[7] << 7);
// ****************************************************
// binary input with 2 buttons and a third read button
// with 1 x 74HC595 shift register
// ****************************************************
// by Philip Prescott-Decie
//*****************************************************

// Arduino to IC 74HC595
int latchPin = 12;  						//IC Pin 12 latch-signal
int clockPin = 11;		 					//IC Pin 11 serial CLK
int dataPin = 13;	 						//IC Pin 13 serial DATA input
int input = 3;								//IC Pin 3 Input QH (output pin normally sent to second register is used to read in data)
int button0 = 2;			  			  	// pin to connect [0] button
int button1 = 4;			  			  	// pin to connect [1] button
int button2 = 5;			  			  	// pin to connect [PRINTOUT] button
int buttonState0 = 0;         				// current state of the [1] button
int lastButtonState0 = 0;     				// previous state of the [1] button
int buttonState1 = 0;         				// current state of the [0] button
int lastButtonState1 = 0;     				// previous state of the [0] button
int buttonState2 = 0;         				// current state of the [0] button
int lastButtonState2 = 0;     				// previous state of the [0] button
int b = 0;									// store binary
int binary[] = {0, 0, 0, 0, 0, 0, 0, 0};	// Array used to store Data from IC - Perhaps possible to change to byte?

void setup()
{
    // Handshake-Connections 
    pinMode(latchPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(button0, INPUT);
	pinMode(button1, INPUT);
	pinMode(button2, INPUT);
    Serial.begin(9200);
}

void loop()
{
    // read the pushbutton input pin:
	buttonState0 = digitalRead(button0);
	buttonState1 = digitalRead(button1);
	buttonState2 = digitalRead(button2);
	
    if (buttonState0 != lastButtonState0) {
		// check for state change
		if (buttonState0 == HIGH) {
			// if the current state is HIGH then the button went from off to on:
			Serial.println("Button 0 on");	  
			digitalWrite(latchPin, LOW); //ground latchPin and hold low for as long as you are transmitting   
			digitalWrite(clockPin, LOW);
			digitalWrite(dataPin, LOW);  // write a zero
			digitalWrite(clockPin, HIGH);
			digitalWrite(latchPin, HIGH); //return the latch pin high to signal chip that it
			delay(250); //add a delay to avoid double entries
		}
	} else {
		if (buttonState1 != lastButtonState1) {
			// check for state change
			if (buttonState1 == HIGH) {
				// if the current state is HIGH then the button went from off to on:
				Serial.println("Button 1 on");	  
				digitalWrite(latchPin, LOW); //ground latchPin and hold low for as long as you are transmitting   
				digitalWrite(clockPin, LOW);
				digitalWrite(dataPin, HIGH);  // write a one
				digitalWrite(clockPin, HIGH);
				digitalWrite(latchPin, HIGH); //return the latch pin high to signal chip that it
				delay(250); //add a delay to avoid double entries
			}
		} else {
			if (buttonState2 != lastButtonState2) {
			// check for state change
				if (buttonState2 == HIGH) {
				// if the current state is HIGH then the button went from off to on:
					Serial.println("Button 2 on");	
					for (int i = 0; i < 8; i++){
						binary[i]=digitalRead(input);
						Serial.println(binary[i]);
						digitalWrite(latchPin, LOW); //ground latchPin and hold low for as long as you are transmitting   
						digitalWrite(clockPin, LOW);
						digitalWrite(dataPin, LOW);  // write a zero
						digitalWrite(clockPin, HIGH);
						digitalWrite(latchPin, HIGH); //return the latch pin high to signal chip that you are done transmitting
						delay(1);
					}
				}
			int b = binary[0] | (binary[1] << 1) | (binary[2] << 2) | (binary[3] << 3) | (binary[4] << 4) | (binary[5] << 5) | (binary[6] << 6) | (binary[7] << 7);
			Serial.println();
			Serial.println("Binary number entered:");
			Serial.println(b);
			}
		// Delay a little bit to avoid bouncing
		delay(100);
		}
	}
}

You are still using an int to hold 8 bits, extracted from 8 more ints.

for(byte i=0; i<8; i++)
{
   bitSet(someByte, i, digitalRead(input));
}

However, I can't see that the value returned by digitalRead() of the pin stored in input is going to return different values just because you read the pin 8 times in very quick succession.

You are going about this somewhat the hard way, because you could just be saving the value as you write it out to the shift register, instead of trying to read it back later.

Also be careful you are getting the correct value read in, since you are reading the input port before doing the shift.

david_2018:
You are going about this somewhat the hard way, because you could just be saving the value as you write it out to the shift register, instead of trying to read it back later.

Also be careful you are getting the correct value read in, since you are reading the input port before doing the shift.

I did think about just using the button inputs, but it felt like a use case for a 595 that I'd never seen before so I wanted to experiment with it.

I also have no idea how to restrict input or store only 8 bits of button presses. The physical shift register corrects for this as if a mistake is made you can just hammer on the 0 button and reset it. I could use the reset line but it felt like an extra button I didn't need.

Again this is my very first project with an Arduino.. Maybe I am going about it all wrong...! Thank you for the reply, maybe I'll try to figure it out your way..

Thank you for all of your advice, I decided to read the input in and then output to the shift registers like you advised. Just incase anyone stumbles on this post in the future here is my completed breadboard binary calculator:

and the code:

/*
 * Arduino Keypad calculator Program
 */

#include <LiquidCrystal.h> //Header file for LCD from https://www.arduino.cc/en/Reference/LiquidCrystal
#include <Keypad.h> //Header file for Keypad from https://github.com/Chris--A/Keypad

int latchPin = 10;  						//IC Pin 12 latch-signal
int clockPin = 9;		 					//IC Pin 11 serial CLK
int dataPin = 11;	 						//IC Pin 13 serial DATA input Shift 1

const byte ROWS = 4; // Four rows
const byte COLS = 4; // Three columns

// Define the Keymap
char keys[ROWS][COLS] = {

  {'1','2','3','A'},

  {'4','5','6','B'},

  {'7','8','9','C'},

  {'*','0','#','D'}

};
byte rowPins[ROWS] = { A0, A1, A2, 8 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 7, 6, 5, 4 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); //  Create the Keypad

const int rs = 13, en = 12, d4 = 3, d5 = 2, d6 = 1, d7 = 0; //Pins to which LCD is connected
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

 long Num1,Num2,Number;
 char key,action;
 boolean result = false;

void setup() {
  lcd.begin(16, 2); //We are using a 16*2 LCD display
  lcd.print("DIY Calculator"); //Display a intro message
  lcd.setCursor(0, 1);   // set the cursor to column 0, line 1
  lcd.print("-CircuitDigest"); //Display a intro message 

  delay(2000); //Wait for display to show info
  lcd.clear(); //Then clean it
  
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void loop() {
  
key = kpd.getKey(); //storing pressed key value in a char

if (key!=NO_KEY)
DetectButtons();

if (result==true)
CalculateResult();

DisplayResult();   
}

void DetectButtons()
{ 
     lcd.clear(); //Then clean it
  if (key=='*'){ //If cancel Button is pressed
    {Serial.println ("Button Cancel"); Number=Num1=Num2=0; result=false;}
	analogWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, (Number >> 8));
    // shift out lowbyte
    shiftOut(dataPin, clockPin, LSBFIRST, Number);
	analogWrite(latchPin, HIGH);
	delay(250);
}
  
     if (key == '1') //If Button 1 is pressed
    {Serial.println ("Button 1"); 
    if (Number==0)
    Number=1;
    else
    Number = (Number*10) + 1; //Pressed twice
    }
    
     if (key == '4') //If Button 4 is pressed
    {Serial.println ("Button 4"); 
    if (Number==0)
    Number=4;
    else
    Number = (Number*10) + 4; //Pressed twice
    }
    
     if (key == '7') //If Button 7 is pressed
    {Serial.println ("Button 7");
    if (Number==0)
    Number=7;
    else
    Number = (Number*10) + 7; //Pressed twice
    } 
  

    if (key == '0')
    {Serial.println ("Button 0"); //Button 0 is Pressed
    if (Number==0)
    Number=0;
    else
    Number = (Number*10) + 0; //Pressed twice
    }
    
     if (key == '2') //Button 2 is Pressed
    {Serial.println ("Button 2"); 
     if (Number==0)
    Number=2;
    else
    Number = (Number*10) + 2; //Pressed twice
    }
    
     if (key == '5')
    {Serial.println ("Button 5"); 
     if (Number==0)
    Number=5;
    else
    Number = (Number*10) + 5; //Pressed twice
    }
    
     if (key == '8')
    {Serial.println ("Button 8"); 
     if (Number==0)
    Number=8;
    else
    Number = (Number*10) + 8; //Pressed twice
    }   
  

    if (key == '#')
    {Serial.println ("Button Equal"); 
    Num2=Number;
    result = true;
     	CalculateResult();
		DisplayResult();
		analogWrite(latchPin, LOW); //pull latch low to send data
     	// shift out highbyte
        shiftOut(dataPin, clockPin, LSBFIRST, (Number >> 8));
        // shift out lowbyte
        shiftOut(dataPin, clockPin, LSBFIRST, Number);
		analogWrite(latchPin, HIGH); //pull latch low to write data
		delay(250);
    }
    
     if (key == '3')
    {Serial.println ("Button 3"); 
     if (Number==0)
    Number=3;
    else
    Number = (Number*10) + 3; //Pressed twice
    }
    
     if (key == '6')
    {Serial.println ("Button 6"); 
    if (Number==0)
    Number=6;
    else
    Number = (Number*10) + 6; //Pressed twice
    }
    
     if (key == '9')
    {Serial.println ("Button 9");
    if (Number==0)
    Number=9;
    else
    Number = (Number*10) + 9; //Pressed twice
    }  

      if (key == 'A' || key == 'B' || key == 'C' || key == 'D') //Detecting Buttons on Column 4
  {
    Num1 = Number;    
    Number =0;
    if (key == 'A')
    {Serial.println ("Addition"); action = '+';}
     if (key == 'B')
    {Serial.println ("Subtraction"); action = '-'; }
     if (key == 'C')
    {Serial.println ("Multiplication"); action = '*';}
     if (key == 'D')
    {Serial.println ("Devesion"); action = '/';}  

    delay(100);
  }
  
}

void CalculateResult()
{
  if (action=='+')
    Number = Num1+Num2;

  if (action=='-')
    Number = Num1-Num2;

  if (action=='*')
    Number = Num1*Num2;

  if (action=='/')
    Number = Num1/Num2; 
}

void DisplayResult()
{
  lcd.setCursor(0, 0);   // set the cursor to column 0, line 1
  lcd.print(Num1); lcd.print(action); lcd.print(Num2); 
  
  if (result==true)
  {lcd.print(" ="); lcd.print(Number);} //Display the result
  
  lcd.setCursor(0, 1);   // set the cursor to column 0, line 1
  lcd.print(Number); //Display the result
}
1 Like