/**
   Mini piano for Arduino.
   You can control the colorful buttons with your keyboard:
   After starting the simulation, click anywhere in the diagram to focus it.
   Then press any key between 1 and 8 to play the piano (1 is the lowest note,
   8 is the highest).
   Copyright (C) 2021, Uri Shaked. Released under the MIT License.
*/
#include "pitches.h"
#define SPEAKER_PIN 8
const int buzzerPin = 11;
const int dataInPin = 2;   /* Q7 */
const int clockInPin = 4;  /* CP */
const int latchInPin = 3;  /* PL */
const int dataOutPin = 5;   /* DS */
const int clockOutPin = 7;  /* SHCP */
const int latchOutPin = 6;  /* STCP */
const int buttonPitches[8] = {262, 294, 330, 349, 392, 440, 494, 523};
bool ledStates[8] = {false, false, false, false, false, false, false, false};
void setup() {
  pinMode(dataOutPin, OUTPUT);
  pinMode(clockOutPin, OUTPUT);  
  pinMode(latchOutPin, OUTPUT);
  pinMode(dataInPin, INPUT);
  pinMode(clockInPin, OUTPUT);  
  pinMode(latchInPin, OUTPUT);
   pinMode(buzzerPin, OUTPUT);
    Serial.begin(9600);
}
void loop() {
uint8_t buttonStates = readButtons();
  
  updateLEDStates(buttonStates);
  
  updateLEDs();
   playNoteFromButton(buttonStates);
  
  
  delay(100); // 延迟一段时间,避免读取按键过于频繁
}
uint8_t readButtons() {
  // 将数据从74HC165芯片读取到Arduino
  
  digitalWrite(latchInPin, LOW); // 拉低锁存引脚
  
  uint8_t buttonStates = 0;
  for (int i = 0; i < 8; i++) {
    // 移位寄存器,读取数据
    digitalWrite(clockInPin, HIGH);
    delayMicroseconds(5); // 等待数据稳定
    digitalWrite(clockInPin, LOW);
    
    bool buttonState = digitalRead(dataInPin); // 读取按钮状态
    
    bitWrite(buttonStates, i, buttonState); // 将按钮状态写入变量
  }
  
  digitalWrite(latchInPin, HIGH); // 提高锁存引脚信号
  
  return buttonStates; // 返回按钮状态
}
void updateLEDStates(uint8_t buttonStates) {
  for (int i = 0; i < 8; i++) {
    bool buttonPressed = bitRead(buttonStates, i);
    ledStates[i] = buttonPressed;
  }
}
void updateLEDs() {
  digitalWrite(latchOutPin, LOW);
  
  for (int i = 7; i >= 0; i--) {
    digitalWrite(clockOutPin, LOW);
    
    bool ledState = ledStates[i];
    digitalWrite(dataOutPin, ledState);
    
    digitalWrite(clockOutPin, HIGH);
  }
  
  digitalWrite(latchOutPin, HIGH);
}
void playNoteFromButton(uint8_t buttonStates) {
  for (int i = 0; i < 8; i++) {
    if (bitRead(buttonStates, i)) {
      playNote(buttonPitches[i]);
    }
  }
}
void playNote(int pitch) {
  tone(buzzerPin, pitch, 200);
  delay(200);
  noTone(buzzerPin);
}