以按键电子琴为基础进行的作品设计,旋钮可以辅助控制节拍,根据音调与节拍的不同会有不同的灯光效果。
作品链接:https://www.tinkercad.com/things/2jJF7ReEkCg
作 者:@王界平 @跳跳熊
在Tinkercad的Circuits板块中,我们可以在线进行简单的电子电路设计以及对应的程序验证,既可以用来尝试新想法新创意,也可以用来给已完成的作品制作示意图和展示图。平台中既有现在流行的Arduino系列单片机及常规的传感器和输出设备,也有更进一步的集成电路、逻辑电路,以及万用表、电源、函数生成器和示波器模块。编程可以通过模块也可以通过语言,适合各阶段用户根据自身进行选择。平台还很贴心的准备了大多数常用器件的范例电路和程序。
我们通过七个按钮和蜂鸣器通过Arduino UNO实现电子琴的基础功能,既按下按钮蜂鸣器发出对应的音调。
D7——NOTE_C5——523;D6——NOTE_D5——587;D5——NOTE_E5——659;D4——NOTE_F5——698;D3——NOTE_G5——784;D2——NOTE_A5——880;D1——NOTE_B5——988
在此基础上加入旋钮接入A5,通过旋钮的当前挡位可以控制音调的持续时间,也就是控制节奏。程序中以旋钮中值512为界限分为4拍和8拍。
通过Neo Pixel Ring 12实现灯光特效,4拍对应流水灯,8拍对应闪烁灯,灯光颜色与对应按钮导线颜色一致。若较长时间没有按键操作,会呈现彩虹灯作为待机模式,按下任意按钮进入工作状态。
- //4拍节奏对应灯效
- void colorWipe(uint32_t c, uint8_t wait) {
- for(uint16_t i=0; i<strip.numPixels(); i++) {
- strip.setPixelColor(i, c);
- strip.show();
- delay(wait);
- }
- }
-
-
- //8拍节奏对应灯效
- void theaterChase(uint32_t c, uint8_t wait) {
- for (int j=0; j<3; j++) {
- for (int q=0; q < 3; q++) {
- for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
- strip.setPixelColor(i+q, c);
- }
- strip.show();
- delay(wait);
- for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
- strip.setPixelColor(i+q, 0);
- }
- }
- }
- }
-
-
- //待机灯效
- uint32_t Wheel(byte WheelPos) {
- WheelPos = 255 - WheelPos;
- if(WheelPos < 85) {
- return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
- }
- if(WheelPos < 170) {
- WheelPos -= 85;
- return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
- }
- WheelPos -= 170;
- return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
- }
-
-
- //清除灯效
- void close() {
- for(uint16_t i=0; i<strip.numPixels(); i++) {
- strip.setPixelColor(i, 0);
- }
- strip.show();
- }
-
-
- //待机控制
- void rainbow(uint8_t wait) {
- uint16_t i, j;
- for(j=0; j<256; j++) {
- for(i=0; i<strip.numPixels(); i++) {
- strip.setPixelColor(i, Wheel((i+j) & 255));
- }
- strip.show();
- delay(wait);
- if(digitalRead(7)==LOW){
- break;
- }
- if(digitalRead(6)==LOW){
- break;
- }
- if(digitalRead(5)==LOW){
- break;
- }
- if(digitalRead(4)==LOW){
- break;
- }
- if(digitalRead(3)==LOW){
- break;
- }
- if(digitalRead(2)==LOW){
- break;
- }
- if(digitalRead(1)==LOW){
- break;
- }
- }
- }
-
- //核心功能
- void musicAndLed(int note, uint32_t c){
- if(analogRead(A5)<512){
- tone(11, note, 250);
- colorWipe(c, 250*1.3/LED);
- close(); // Close
- noTone(11);
- }
- else{
- tone(11, note, 125);
- theaterChase(c, 125*1.3/9);
- close(); // Close
- noTone(11);
- }
- noTone(11);
- time=millis();
- }
-
-
- //逻辑主体
- Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED, PIN, NEO_GRB + NEO_KHZ800);
- int time;
- void setup() {
- #if defined (__AVR_ATtiny85__)
- if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
- #endif
- strip.begin();
- strip.show();
- }
- void loop() {
- close(); // Close
- noTone(11);
- if(digitalRead(7)==LOW){
- musicAndLed(NOTE_C5, strip.Color(255, 97, 0));
- while(digitalRead(7)==LOW){ }
- }
- if(digitalRead(6)==LOW){
- musicAndLed(NOTE_D5, strip.Color(255, 215, 0));
- while(digitalRead(6)==LOW){ }
- }
- if(digitalRead(5)==LOW){
- musicAndLed(NOTE_E5, strip.Color(34, 139, 34));
- while(digitalRead(5)==LOW){ }
- }
- if(digitalRead(4)==LOW){
- musicAndLed(NOTE_F5, strip.Color(64, 224, 208));
- while(digitalRead(4)==LOW){ }
- }
- if(digitalRead(3)==LOW){
- musicAndLed(NOTE_G5, strip.Color(0, 0, 255));
- while(digitalRead(3)==LOW){ }
- }
- if(digitalRead(2)==LOW){
- musicAndLed(NOTE_A5, strip.Color(153, 51, 250));
- while(digitalRead(2)==LOW){ }
- }
- if(digitalRead(1)==LOW){
- musicAndLed(NOTE_B5, strip.Color(115, 74, 18));
- while(digitalRead(1)==LOW){ }
- }
- if(millis()-time>2000){
- rainbow(20);
- }
- }
复制代码
|