/*
// File : Cascade165.ino
//
// Version 1, 5 August 2021, by Koepel
// Initial version.
// Version 2, 5 August 2021, by Koepel
// Layout of the wiring made better.
// Version 3, 13 August 2021, by Koepel
// Changed 'SCK' to 'clockPin'.
//
// Cascade of four 74HC165 shift-in registers.
// Only three pins are used on the Arduino board, to read 32 switches.
//
// Using the 74HC165 is safe, because a pulse to the Latch pin
// ('PL' on the 74HC165) will make a new start every time.
// In case of an error or a wrong clock pulse by noise,
// it synchronizes the data when inputs are read the next time.
//
// Based on:
// (1)
// Demo sketch to read from a 74HC165 input shift register
// by Nick Gammon, https://www.gammon.com.au/forum/?id=11979
// (2)
// 74HC165 Shift register input example
// by Uri Shaked, https://wokwi.com/arduino/projects/306031380875182657
//***********************************************************************************
//***********************************************************************************
//***********************************************************************************
// ****************************************************
// binary LED - runner
// with 2 x 74HC595 shift register
// 8-Bit Output cascadable over Pin 16 to 2nd IC Pin 14
// ****************************************************
// by Walter Kofler
//*****************************************************
// Arduino to IC 74HC595
int RCLK_latch_Pin_12 = 12; //IC Pin 12 latch-signal
int SRCLC_Pin_11 = 11; //IC Pin 11 serial CLK
int SER_data_Pin_14 = 13; //IC Pin 14 serial DATA input
// intern var's
byte HBYTE = 0;
byte LBYTE = 0;
int HByte;
int LByte;
long Counter = 0; //LED counter
//long oldCounter = 0; //previous Counter
int LEDisON = 0; //true if LED is on
//***********************************************************************************
//***********************************************************************************
*/
/*
// in orig sketch pins were latch9;clock13;data12
const byte latchPin = 3; // to latch the inputs into the registers
const byte clockPin = 7; // I choose the SCK pin
const byte dataPin = 6; // I choose the MISO pin
uint16_t oldOptionSwitch = 65535; // previous state of all the inputs
const int pulseWidth = 10; // pulse width in microseconds
*/
//Try something simpler.
//Use pin9 to latch 165 data
//use pin10 to latch 595 data
//connect SCK (d13) to all clock lines/
//connect MISO (d12) to 165 data out
//connect MOSI (d11) to 595 data in
const int buzzer = 7; //buzzer to arduino pin 7
byte byte1 = 0;
byte byte2 = 0;
byte oldbyte1 = 0;
byte oldbyte2 = 0;
byte rndbyte1 = 0;
byte rndbyte2 = 0;
const byte latch165 = 9;
const byte latch595 = 10;
const byte clockPin = 13; // I choose the SCK pin
const byte dataPin = 12; // I choose the MISO pin
const int pulseWidth = 10; // pulse width in microseconds
byte HBYTE = 0;
byte LBYTE = 0;
int HByte;
int LByte;
long Counter = 0;
boolean checkit = 0;
#include <SPI.h>
void setup ()
{
pinMode(buzzer, OUTPUT); // Set buzzer - pin 7 as an output
//Serial.begin(115200);
Serial.begin(9600);
SPI.setBitOrder(LSBFIRST);
SPI.setDataMode(SPI_MODE1);
SPI.begin();
/* Serial.begin( 115200);
Serial.println( "Turn on and off the switches");
Serial.println( "Top row is switch 0 (right) to switch 7 (left)");
Serial.println( "Second row is 8 to 15, and so on");
pinMode( clockPin, OUTPUT); // clock signal, idle LOW
pinMode( latchPin, OUTPUT); // latch (copy input into registers), idle HIGH
digitalWrite( latchPin, HIGH);
//595
// Handshake-Connections
pinMode(RCLK_latch_Pin_12, OUTPUT);
pinMode(SER_data_Pin_14, OUTPUT);
pinMode(SRCLC_Pin_11, OUTPUT);
intern
set Counter to B0000000000000001
Counter = 1;
Serial.begin(9200);
randomSeed(analogRead(0));
//end 595
*/
randomSeed(analogRead(0));
}
//BEGIN!
void loop ()
{
//sendtoLED595(0,0); //turn off leds
playme(250); //buzzer
wylosuj(); //output rndbyte1 and rndbyte2
///sendtoLED595(byte1,byte2);
sendtoLED595(rndbyte1,rndbyte2);
Serial.print("rndbyte1= ");
Serial.println(rndbyte1);
Serial.print("rndbyte2= ");
Serial.println(rndbyte2);
while(anyKey()==0){} //Wait for an input, the anyKey function throws TRUE when it gets a press
ReadBoth165(); //Read and output to byte1 and byte2
Serial.print("byte1= ");
Serial.println(byte1);
Serial.print("byte2= ");
Serial.println(byte2);
checkit = (byte1==rndbyte1) && (byte2==rndbyte2);
Serial.print("checkit= ");
Serial.println(checkit);
if (checkit == 1) playme(2000); //buzzer
//byte1 = 0;
//byte2 = 0;
//digitalWrite (latch165, LOW);
//delay( 25); // slow down the sketch to avoid switch bounce
//digitalWrite (latch165, HIGH); // capture 165 inputs
//byte1 = ReadOne165();
//byte2 = ReadOne165();
//byte1 = SPI.transfer(0); // read in 165 #2 data
//delay( 25); // slow down the sketch to avoid switch bounce
//byte2 = SPI.transfer(0); // read in 165 #1 data
/*
Serial.print("165byte1= ");
Serial.println(byte1);
Serial.print("165byte2= ");
Serial.println(byte2);
*/
//sendtoLED595();
/*
//wait 100ms
delay(200);
//SPI.transfer(255-byte1); // send data to 595 #1
SPI.transfer(byte1); // send data to 595 #1
delay( 25); // slow down the sketch to avoid switch bounce
//SPI.transfer(255-byte2); // send data to 595 #2
SPI.transfer(byte2); // send data to 595 #2
Serial.print("595byte1= ");
Serial.println(byte1);
Serial.print("595byte2= ");
Serial.println(byte2);
//digitalWrite (latch595, LOW);
//digitalWrite (latch595, HIGH); // latch to output of 595s.
//delay( 25); // slow down the sketch to avoid switch bounce
//delay(1000);
//Serial.println("----------------------------------------------");
*/
/*
//***********************************************************************************
//**595****************
//Serial.print("LEDisON= ");
// Serial.println(LEDisON);
if (LEDisON <1) //if LED is off
{
Counter = 0;
Serial.print("LEDisON po if= ");
Serial.println(LEDisON);
//serial Data to control action
Serial.print(" Counter before= ");
Serial.print(Counter);
//***generate Counter with one random bit ON
//while (oldCounter == Counter)
//{
bitSet(Counter, random(16));
//Serial.print(" Counter while= ");
// Serial.println(Counter);
// Serial.print(" oldCounter while= ");
// Serial.println(oldCounter);
//}
//serial Data to control action
Serial.print(" Counter after= ");
Serial.print(Counter);
//******************
//splitt Long_integer to Low_Byte and Hight_Byte
LByte = Counter & B11111111;
HByte = abs(Counter / 256);
LBYTE = LByte;
HBYTE = HByte;
//serial Data to control action
Serial.print(" Counter= ");
Serial.print(Counter);
Serial.print(" LByte = ");
Serial.print(LByte);
Serial.print(" HByte = ");
Serial.println(HByte);
//IC Control
//1. Latch down
digitalWrite(RCLK_latch_Pin_12, LOW);
//2. Data_shiftout 2x8Bit
shiftOut(SER_data_Pin_14,SRCLC_Pin_11, MSBFIRST, HBYTE);
shiftOut(SER_data_Pin_14,SRCLC_Pin_11, MSBFIRST, LBYTE);
//3. Latch active
digitalWrite(RCLK_latch_Pin_12, HIGH);
LEDisON = 1; //LED is lite
// Serial.print("LEDis0000000ON= ");
// Serial.println(LEDisON);
//wait 100ms
delay(1000);
//end 595
//***********************************************************************************
//***********************************************************************************
}
//oldCounter = Counter;
// Give a pulse to the parallel load latch of all 74HC165
digitalWrite( latchPin, LOW);
delayMicroseconds( pulseWidth);
digitalWrite( latchPin, HIGH);
// Reading one 74HC165 at a time and combining them into a 32 bit variable
// The last 74HC165 is at the bottom, but the switches start numbering
// at the top. So the first byte has to be shifted into the highest place.
uint16_t optionSwitch = 0;
//for( int i=24; i>=0; i-=8)
for( int i=8; i>=0; i-=8)
{
optionSwitch |= ((uint16_t) ReadOne165()) << i;
}
for( int i = 0; i<32; i++)
{
if( bitRead( optionSwitch, i) != bitRead( oldOptionSwitch,i))
{
Serial.print("optionSwitch= ");
Serial.println(optionSwitch);
Serial.print("Counter= ");
Serial.println(Counter);
Serial.print( "Switch ");
if( i < 10)
Serial.print( " ");
Serial.print( i);
Serial.print( " is now ");
Serial.println( bitRead( optionSwitch, i) == 0 ? "down ↓" : "up ↑");
Serial.println( optionSwitch+Counter == 65535 ? "=====HURRRAAA====" : "----Neeee----");
LEDisON = 0;// no testing for the time being
}
}
oldOptionSwitch = optionSwitch;
delay( 25); // slow down the sketch to avoid switch bounce
//***********************************************************************************
*/
//koniec programu
Serial.print("**********************************************");
}
// The ReadOne165() function reads only 8 bits,
// because of the similar functions shiftIn() and SPI.transfer()
// which both use 8 bits.
//
// The shiftIn() can not be used here, because the clock is set idle low
// and the shiftIn() makes the clock high to read a bit.
// The 74HC165 require to read the bit first and then give a clock pulse.
//
byte ReadOne165()
{
byte ret = 0x00;
// The first one that is read is the highest bit (input D7 of the 74HC165).
for( int i=7; i>=0; i--)
{
if( digitalRead( dataPin) == HIGH)
bitSet( ret, i);
digitalWrite( clockPin, HIGH);
delayMicroseconds( pulseWidth);
digitalWrite( clockPin, LOW);
}
return( ret);
}
void playme (int freq) {
//buzzer
tone(buzzer, freq); // Send 1KHz sound signal...
delay(1000); // ...for 1 sec
noTone(buzzer); // Stop sound...
delay(1000); // ...for 1sec
//end buzzer
}
// void ReadBoth165(byte byte1, byte byte2) {
void ReadBoth165() {
digitalWrite (latch165, LOW);
delay( 25); // slow down the sketch to avoid switch bounce
digitalWrite (latch165, HIGH); // capture 165 inputs
byte1 = ReadOne165();
byte2 = ReadOne165();
}
void wylosuj() {
Counter = 0;
bitSet(Counter, random(16));
//splitt Long_integer to Low_Byte and Hight_Byte
LByte = Counter & B11111111;
HByte = abs(Counter / 256);
LBYTE = LByte;
HBYTE = HByte;
rndbyte1 = LByte;
rndbyte2 = HByte;
}
void sendtoLED595 (byte byte595_1, byte byte595_2) {
//wait 200ms
delay(200);
//SPI.transfer(255-byte1); // send data to 595 #1
SPI.transfer(byte595_1); // send data to 595 #1
delay( 25); // slow down the sketch to avoid switch bounce
//SPI.transfer(255-byte2); // send data to 595 #2
SPI.transfer(byte595_2); // send data to 595 #2
/*
Serial.print("595byte1= ");
Serial.println(byte1);
Serial.print("595byte2= ");
Serial.println(byte2);
*/
digitalWrite (latch595, LOW);
digitalWrite (latch595, HIGH); // latch to output of 595s.
delay( 25); // slow down the sketch to avoid switch bounce
//delay(1000);
}
boolean anyKey(){
boolean press = 0;
ReadBoth165();
if((byte1!=oldbyte1)){
press = 1;
}
if((byte2!=oldbyte2)){
press = 1;
}
/*
Serial.print("oldbyte1= ");
Serial.println(oldbyte1);
Serial.print("oldbyte2= ");
Serial.println(oldbyte2);
Serial.print("byte1= ");
Serial.println(byte1);
Serial.print("byte2= ");
Serial.println(byte2);
Serial.print("press= ");
Serial.println(press);
*/
delay( 200);
return press;
}