/**
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);
}