/*
This sketch demonstrates polling the inputs of a 74HC165 8-Bit Parallel-Load Shift Register
using the Arduino SPI interface. You should connect pushbuttons or switches to the inputs
of the 74HC165. Also connect an LED to Arduino D9 (aka pin 15) for testing.
If you don't use all of the inputs of the 74HC165, make sure to tie them to ground.
ARDUINO
=======
For pin mappings, see http://arduino.cc/en/Hacking/PinMapping168
----_----
vcc - [RST] |1 28| [A5]
[RX] |2 A 27| [A4]
[TX] |3 T 26| [A3]
[D2] |4 M 25| [A2]
[D3] |5 E 24| [A1]
[D4] |6 G 23| [A0]
vcc - [+v] |7 A 22| [GND] - gnd
gnd - [GND] |8 21| [AREF] - aref
crystal - [XTL1] |9 3 20| [AVCC] - avcc
crystal - [XTL2] |10 2 19| [D13] - SPI SCK (clock)
[D5] |11 8 18| [D12] - SPI MISO (master in, slave out)
[D6] |12 17| [D11] - SPI MOSI (master out, slave in)
[D7] |13 16| [D10] - SPI SS (slave select)
[D8] |14 15| [D9]
---------
Arduino Connections:
Connect [D13] to the Clock pin of the SN74HC165 (pin 2)
Connect [D12] to the Qh pin of the SN74HC165 (pin 9)
Connect [D11] to nothing. It's not used in this sketch
Connect [D9] to an LED for testing
Connect [D6] to the SH/LD pin of the SN74HC165 (pin 1)
SN74HC165 SHIFT REGISTER
========================
----_----
Arduino [D6] (pin 12) <- SH/LD - |1 16| - Vcc -> tied to +5 volts
Arduino [D13] (pin 19) <- CLK - |2 7 15| - CLK INH -> tied to ground
E - |3 4 14| - D
F - |4 H 13| - C
G - |5 C 12| - B
H - |6 1 11| - A
Arduino [D12] (pin 18) <- Qh - |7 6 10| - SER -> unused, but tie to ground
gnd - |8 5 9| - Qh' -> not connected
---------
Shift register connections:
Connect inputs A,B,C,D,E,F,G and H to either pushbuttons or switches.
Connect SH/LD (pin 1) to the Arduino [D6] digital output (pin 12)
Connect CLK (pin 2) to the Arudino [D13] digital output (pin 19)
Connect Qh (pin 7) to the Ardino [D12] digital input (pin 18)
Connect CLK INH (pin 15) to ground
Connect SER (pin 10) to ground
*/
#include <SPI.h>
// PINs Define
#define SPI_sck 13 // Arduino [D13] - (ATMega 328 pin 19) - SPI clock
#define SPI_miso 12 // Arduino [D12] - (ATMega 328 pin 18) - SPI master in, slave out
#define SPI_mosi 11 // Arduino [D11] - (ATMega 328 pin 17) - SPI master out, slave in
#define SPI_ss 10 // Arduino [D10] - (ATMega 328 pin 16) - SPI slave select
#define PLSR_SH_LD_pin 6 // Arduino Pin D6 - (ATMega 328 pin 12) -> SH/LD pin (pin 1) of
// octave is 12 length
#define FIRST_NOTE 24
#define SH_REG_NB 4 // number of shift register plugged
#define OUT_PER_SH_REG 8 // number of outputs on a shift register
#define KEY_NB (OUT_PER_SH_REG * SH_REG_NB) // number of key/buttons connected to shift register
uint8_t keys[SH_REG_NB];
uint8_t keys_prev[SH_REG_NB];
// sort by octave
char* Notes[128] =
{
"C-1", "C#-1", "D-1", "Eb-1", "E-1", "F-1", "F#-1", "G-1", "G#-1", "A-1", "Bb-1", "B-1",
"C0", "C#0", "D0", "Eb0", "E0", "F0", "F#0", "G0", "G#0", "A0", "Bb0", "B0",
"C1", "C#1", "D1", "Eb1", "E1", "F1", "F#1", "G1", "G#1", "A1", "Bb1", "B1",
"C2", "C#2", "D2", "Eb2", "E2", "F2", "F#2", "G2", "G#2", "A2", "Bb2", "B2",
"C3", "C#3", "D3", "Eb3", "E3", "F3", "F#3", "G3", "G#3", "A3", "Bb3", "B3",
"C4", "C#4", "D4", "Eb4", "E4", "F4", "F#4", "G4", "G#4", "A4", "Bb4", "B4", // C4 middle C between G and F keys
"C5", "C#5", "D5", "Eb5", "E5", "F5", "F#5", "G5", "G#5", "A5", "Bb5", "B5",
"C6", "C#6", "D6", "Eb6", "E6", "F6", "F#6", "G6", "G#6", "A6", "Bb6", "B6",
"C7", "C#7", "D7", "Eb7", "E7", "F7", "F#7", "G7", "G#7", "A7", "Bb7", "B7",
"C8", "C#8", "D8", "Eb8", "E8", "F8", "F#8", "G8", "G#8", "A8", "Bb8", "B8"
"C9", "C#9", "D9", "Eb9", "E9", "F9", "F#9", "G9",
};
// sort by shift register (8 values / line)
/*
"C-1", "C#-1", "D-1", "Eb-1", "E-1", "F-1", "F#-1", "G-1",
"G#-1","A-1", "Bb-1","B-1", "C0", "C#0", "D0", "Eb0",
"E0", "F0", "F#0", "G0", "G#0", "A0", "Bb0", "B0",
"C1", "C#1", "D1", "Eb1", "E1", "F1", "F#1", "G1",
"G#1", "A1", "Bb1", "B1", "C2", "C#2", "D2", "Eb2",
"E2", "F2", "F#2", "G2", "G#2", "A2", "Bb2", "B2",
"C3", "C#3", "D3", "Eb3", "E3", "F3", "F#3", "G3",
"G#3", "A3", "Bb3", "B3", "C4", "C#4", "D4", "Eb4",
"E4", "F4", "F#4", "G4", "G#4", "A4", "Bb4", "B4",
"C5", "C#5", "D5", "Eb5", "E5", "F5", "F#5", "G5",
"G#5", "A5", "Bb5", "B5", "C6", "C#6", "D6", "Eb6",
"E6", "F6", "F#6", "G6", "G#6", "A6", "Bb6", "B6",
"C7", "C#7", "D7", "Eb7", "E7", "F7", "F#7", "G7",
"G#7", "A7", "Bb7", "B7", "C8", "C#8", "D8", "Eb8",
"E8", "F8", "F#8", "G8", "G#8", "A8", "Bb8", "B8"
"C9", "C#9", "D9", "Eb9", "E9", "F9", "F#9", "G9",
*/
void setup() {
pinMode(SPI_ss, OUTPUT);
Serial.begin(115200);
// Set up the SPI bus
SPI.begin();
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV2);
// Set pinmodes for the digital outputs
pinMode(PLSR_SH_LD_pin, OUTPUT);
// Tell the SN74HC165 Parallel-load shift register to poll the inputs
digitalWrite(PLSR_SH_LD_pin, LOW);
readShiftRegisterSPI(); // to init array
}
void loop() {
// put your main code here, to run repeatedly:
readShiftRegisterSPI();
manageKeysShiftRegister();
delay(5);
}
//SH_REG_NB
//OUT_PER_SH_REG
//KEY_NB
void readShiftRegisterSPI()
{
// store previous keys values
memcpy(keys_prev, keys, SH_REG_NB);
// Latch the inputs into the shift register
digitalWrite(PLSR_SH_LD_pin, HIGH);
// read value of different shift registers
for(uint8_t shReg = 0; shReg < SH_REG_NB; shReg ++)
{
keys[shReg] = SPI.transfer(0x00);
}
// Start polling the inputs again
digitalWrite(PLSR_SH_LD_pin, LOW);
// for(uint8_t shReg = SH_REG_NB; shReg > 0; shReg --)
// {
// for(uint8_t b = 0; b < OUT_PER_SH_REG; b++)
// Serial.print(bitRead(keys[shReg-1],b), BIN);
// Serial.print(" - ");
// }
// Serial.println();
}
void manageKeysShiftRegister()
{
uint8_t id = FIRST_NOTE + KEY_NB; // set offset first note
for(uint8_t reg = 0; reg < SH_REG_NB; reg++)
{
id -= OUT_PER_SH_REG;
if(keys[reg] != keys_prev[reg]) // a value has changed in this register
{
for(uint8_t b = 0; b < OUT_PER_SH_REG; b++)
{
if(((keys[reg]>>b)&0x1) != ((keys_prev[reg]>>b)&0x1))
{
Serial.print(Notes[id + b]);
Serial.println(((keys[reg]>>b)&0x1) ? " ON" : " OFF");
}
}
}
}
}