用arduino单片机和步进电机制作手掌大的电子琴

2022-05-142.8万
精华项目
AI 快速预览详细 收起
本文介绍了如何使用Arduino单片机和42步进电机制作一款手掌大小的电子琴。项目名称为Stepper Music,硬件清单包括Arduino Nano控制器、42步进电机、A4988驱动等。最终效果是通过改变步进电机的频率,实现音乐弹奏。难度等级适中,适合STEM教育和少儿编程入门。
用arduino单片机和步进电机制作手掌大的电子琴图1


图 1 步进电机琴


#项目起源#

步进电机大家或多或少都接触过,常见在一些中小型的加工设备中,比如激光切割机或者3D打印机,旺仔爸爸在使用激光切割机的时候就发现,在切割圆形的图案时,激光切割机中的步进电机就会发出类似于乐器弹奏的声音,为什么会出现这种现象呢?

用arduino单片机和步进电机制作手掌大的电子琴图2


图 2 激光切割机的步进电机


我们都知道,声音的产生与频率有关,频率越高,声音就会越尖。扬声器就是因为响应了不同的频率才发出不同的声音而如果要控制激光切割机的步进电机工作就需要改变频率,那么频率的改变是不是就可以让步进电机发出不同的声音呢?如果真的是这样,那么理论上一首完整的音乐也是可以使用步进电机弹奏出来的,本期内容我们就一起来探究一下这个问题,使用步进电机来制作一款电子琴,因为它是由步进电机制作的,所以我给它取名叫Stepper Music

下面我们先通过视频来看一下步进电机电子琴是如何设计制作的

#视频展示#



#设计制作#    

作品设计的第一步,需要确定设计方案,这次设计的步进电机电子琴需要利用步进电机来发音,同时还需要有类似于钢琴的琴键,要具有按下回弹的效果,通过以上分析,我们将步进电机琴拆分成三部分,分别是:步进电机、外观结构框架和电控部分

电控部分



    与真实钢琴不同的是,本次作品要使用步进电机来发出声音,要控制步进电机的话就需要一个步进电机驱动器,常见的步进电机驱动为A4988驱动,常用在早期的3D打印机中,由于A4988驱动噪音比较大,逐渐被更优的方案代替。不过我们这次的主要目的就是为了让步进电机发声,所以噪音对于我们来说反而是好事情。步进电机驱动器型号确定后,我们再来确定控制器,控制器我们选择常用的Arduino单片机,为了缩小体积,我们选择Nano系列版本。同时为了减少布线,使用起来更加方便,我们将控制器、步进电机驱动以及琴键集成设计在一块电路板上,电路板仿真效果图如下


用arduino单片机和步进电机制作手掌大的电子琴图3


图 3步进电机琴电路板


此电路板的原理图如下,主要包含一个电源电路,控制器,驱动器电路等。其中,轻触开关在电路中设计了一个上拉电阻让其信号变得稳定


用arduino单片机和步进电机制作手掌大的电子琴图4


图 4 原理图


原理图绘制完成后就可以将原理图生成PCB文件了,紧接着我们根据原理图进行布线,为了保证步进电机工作时的电流,布线线宽参数要设置的大一些

用arduino单片机和步进电机制作手掌大的电子琴图5


图 5 PCB布线


PCB设计完成后切换至三维模式查看3D效果


用arduino单片机和步进电机制作手掌大的电子琴图6


图 6 PCB三维图


最后检查没有问题后就可以送去打样了


在PCB板打样的同时,我们可以着手准备需要用到的焊接元件,元件材料BOM表如下:


用arduino单片机和步进电机制作手掌大的电子琴图7


图 7 零件清单


打样完成后的PCB实物如下图


用arduino单片机和步进电机制作手掌大的电子琴图8


图 8 PCB实物


元件材料准备齐全后,我们将元件依次焊接在电路板中


焊接完成,成品如下图,其中A4988驱动和Arduino Nano控制器需要自行购买


用arduino单片机和步进电机制作手掌大的电子琴图9


图 9 PCB焊接完成


电控部分设计完成, 接下来为步进电机电子琴设计外观结构


外观结构


    步进电机电子琴的外观结构我们参考现实生活中的钢琴模样来设计,采用激光切割技术来加工制作,下图10为效果图    本次我们要制作的步进电机电子琴的特点是它的体积只有手掌大小,而现实生活中的钢琴琴键会有80几个之多,既要保证有很丰富的音调,又要保证体积。这里我们借助一颗电位器来调节音调,当电位器调节至不同的档位,按下琴键就会发出不同的音调,这样就实现了使用7个琴键模拟多种音调的效果了

用arduino单片机和步进电机制作手掌大的电子琴图10


图 10 步进电机琴的效果仿真图


    步进电机电子琴外观结构的关键部位是琴键,需要同时满足能够发声,又能有按下后回弹的感觉,这里我们采用了微动开关(轻触开关)作为琴键,在琴键的结构中,加入柔性设计的结构使得琴键能够回弹


用arduino单片机和步进电机制作手掌大的电子琴图11


图 11琴键设计


步进电机


至于,本次使用的步进电机,我们采用最常见的42两相四线步进电机(42为长宽尺寸,单位mm,两相即为两组线圈)

方案确定后,我们便可开始设计制作了首先来设计外观结构的图纸

图纸设计

为了验证装配细节,我们先使用Fusion360计算机辅助设计软件设计三维模型,再将模型转换为适合激光切割加工的二维图纸。其中材料选择3mm的椴木板

用arduino单片机和步进电机制作手掌大的电子琴图12


图 12 三维仿真效果图


三维模型设计完成后,将图纸加载至LaserMaker激光建模软件中做处理关于LserMaker建模软件可以登录官方提供的网址下载:https://www.lasermaker.com.cn/


在软件中设置文本和图案为浅雕加工工艺,步进电机在工作时是会旋转的,我们为它设计一个刻有两条鱼的转盘,增加旋转效果。处理完成的设计图如下,

用arduino单片机和步进电机制作手掌大的电子琴图13


图 13 步进电机“钢琴”设计图


加工零件

图纸设计完成后我们使用激光切割机把它加工出来,切割完成后的零件如下图14所示


用arduino单片机和步进电机制作手掌大的电子琴图14


图 14 激光切割加工完成后的零件实物图


器材清单


除了以上外观结构外,本次步进电机电子琴还需要使用到如下零件

  • Arduino Nano控制器及扩展板*1
  • A4988驱动*2
  • 42步进电机*1
  • 电位器*1
  • 3mm椴木板*1(40cm*60cm)
  • 杜邦线若干
  • 五金件若干


用arduino单片机和步进电机制作手掌大的电子琴图15


图 15 步进电机琴的器材清单


器材准备完成,接下来我们看一下电控部分是如何接线的


电路接线


这次我们将电路设计分为PCB设计和电路接线两部分关于步进电机“钢琴”的PCB电路板在前面我们已经设计完成,现在我们来看一下电位器、步进电机与控制板是如何接线的接线图如下,从接线图中我们可以看出,控制板预留了两个步进电机的连接端口,我们可以连接一个或两个步进电机,电位器可以连接A0模拟引脚,而板载的7个轻触开关分别对应D6至D12数字引脚

用arduino单片机和步进电机制作手掌大的电子琴图16


图 16 步进电机电子琴电路接线示意图


一切准备工作就绪,我们即可开始进入激动人心的组装环节了


#组装#

步进电机电子琴的组装不算很复杂,只需几步即可完成


第一步 安装电子部件

首先我们安装电路板部分,电路板中轻触开关的部分朝上与木板组合在一起,使用直径3mm的螺丝、螺母和尼龙柱固定,如下图17和图18


用arduino单片机和步进电机制作手掌大的电子琴图17


图 17 电路板安装


用arduino单片机和步进电机制作手掌大的电子琴图18


图 18 电路板安装完成


紧接着,安装电位器,下图19是所需的零件


用arduino单片机和步进电机制作手掌大的电子琴图19


图 19 安装电位器


先将电位器安装在对应的方孔中,然后套上旋钮帽,电位器安装完成如下图20所示


用arduino单片机和步进电机制作手掌大的电子琴图20


图20 电位器安装完成


接下来,我们将刻有小鱼的圆形转盘与步进电机安装在一起,如下图21所示


用arduino单片机和步进电机制作手掌大的电子琴图21


图 21 小鱼转盘与步进


第二步 组装框架结构


电子部件安装完成,下面一步我们需要将框架组装起来,首先安装如下部分框架


用arduino单片机和步进电机制作手掌大的电子琴图22


图 22 框架组装需要的零件


部分框架组装完成如下图23所示


用arduino单片机和步进电机制作手掌大的电子琴图23


图 23 框架组装完成


随后我们在上面的基础上安装琴键木板和中间的一块竖板,所需零件如下图24


用arduino单片机和步进电机制作手掌大的电子琴图24


图 24安装琴键和竖板


琴键和竖板组装完成如下图25所示


用arduino单片机和步进电机制作手掌大的电子琴图25


图 25 琴键和竖板组装完成


接着安装用来固定电位器和步进电机的顶板,所需零件如下图26所示


用arduino单片机和步进电机制作手掌大的电子琴图26


图 26 安装顶板


顶板安装完成如下图27,安装时注意电位器的旋钮指示标志的方向


用arduino单片机和步进电机制作手掌大的电子琴图27


图 27 顶板安装完成


下面一步,需要将左侧的木板安装在框架上


用arduino单片机和步进电机制作手掌大的电子琴图28


图 28 安装左侧木板


左侧木板安装完成如图29


用arduino单片机和步进电机制作手掌大的电子琴图29


图 29 左侧木板安装完成


最后将背板安装在框架上


用arduino单片机和步进电机制作手掌大的电子琴图30


图 28 安装背板


再使用两个插销固定,安装完成如下图29


用arduino单片机和步进电机制作手掌大的电子琴图31


图 29背板安装完成


外观结构框架组装完成,效果展示


用arduino单片机和步进电机制作手掌大的电子琴图32


图 30外观结构框架组装完成


用arduino单片机和步进电机制作手掌大的电子琴图33


图 31外观结构框架组装完成


第三步 放置步进电机


第三步,将步进电机按照下图的方式放入琴中,注意在放入琴中之前需要先将电路连接完成




图 32 放置步进电机


用arduino单片机和步进电机制作手掌大的电子琴图34


图 33 步进电机“钢琴”正面展示


用arduino单片机和步进电机制作手掌大的电子琴图35


图 34 步进电机“钢琴”反面展示


如果你也喜欢小巧的步进电机电子琴,又不想动手的话,可以点击下面的小程序选购哦




作品组装完成,接下来我们编写程序为作品注入灵魂

#程序设计#

为了保证步进电机的响应速度,本次步进电机电子琴的程序需要直接对单片机的寄存器编程,而不使用arduino库中提供的digitalWrite这样的函数。所以,本次作品程序设计使用Arduino IDE作为编程环境,关于编程环境可以在官网arduino.cc下载


用arduino单片机和步进电机制作手掌大的电子琴图36


图 35


当然也可以在mixly.org网站下载最新的Mixly图形化编程软件,软件中集成了Arduino IDE编程环境,省去了不少配置的麻烦


编程思路


本次我们制作的步进电机电子琴(Stepper Music),程序设计的重点在于如何让步进电机快速的响应不同的频率,然后发出不同的声音,下面是编程思路,我们根据编程思路来一步步完成

用arduino单片机和步进电机制作手掌大的电子琴图37


图 36 程序设计思维导图



步进电机的驱动方法



在学习步进电机驱动方法之前先来补充一下步进电机的背景知识


步进电机背景知识


用arduino单片机和步进电机制作手掌大的电子琴图38


本次我们所使用的是42步进电机,其实它的学名叫NEMA双极性两相四线步进电机,NEMA是美国“National Electrical Manufacturers Association(国家电气制造协会)”的缩写,在1984年,美国国家电气制造协会(NEMA)根据电机尺寸制定了一系列标准,其中就包含“NEMA17”步进电机,NEMA17中的17指的是电机的机座尺寸是1.7英寸(约为42毫米,因此NEMA17步进电机也常被称作42步进电机)。这套标准,直到今天仍在使用。其中两相的概念表示由两组线圈组成。“NEMA17”步进电机在3D打印机领域应用非常广泛。

除此之外,更大尺寸的“NEMA23”步进电机,也就是我们常说的 57步进电机,则被更多地使用在了激光切割机领域

用arduino单片机和步进电机制作手掌大的电子琴图39


图 37 42步进电机


了解了步进电机的尺寸,我们还需要知道步进电机的基本参数


1.步进电机步距角

本次我们使用的42步进电机的步距角是1.8°,简单的理解步距角就是,控制器每发出一个步进脉冲信号,电机转动的角度,是出厂时给出的一个数值,当然在工作时也可以通过驱动器来调节步距角,至于步距角为什么是1.8°,这里我们就不详解讲解了,你只需要知道这个步距角与电机内部的齿数有关,齿数越细分,步距角越小

2.步进电机相数

步进电机的相数,简单的理解就是电机内部线圈的组数,常见的有两相、三相、四相、五相等,常见的一款小型步进电机就是四相五线步进电机,适合用在对力矩要求不是很高的场合


用arduino单片机和步进电机制作手掌大的电子琴图40


图 38


我们这次使用的是两相四线步进电机,从下图中可以看出,两相四线步进电机有8个线圈,其中每四个线圈为一项

用arduino单片机和步进电机制作手掌大的电子琴图41


图 39 42步进电机线圈


只有步进电机还不够,我们还需要步进电机驱动才能使步进电机工作

A4988驱动从前文中我们知道,本次作品我们选用A4988步进电机驱动,它是一款十分普及且性价比很高的驱动板,尤其是在3D打印和小型CNC数控机床领域十分常见

用arduino单片机和步进电机制作手掌大的电子琴图42


图 40 A4988驱动器


要使用驱动器驱动步进电机我们需要掌握A4988驱动器的每个引脚功能,A4988引脚功能示意图如下

用arduino单片机和步进电机制作手掌大的电子琴图43


图 41 A4988驱动器


通过下面的表格我们可以知道驱动板的每个引脚功能,步进电机需要连接1A、1B、2A、2B引脚,而步距角我们可以使用默认的全步进方式,在程序中我们只需要设置STEP和DIR两个引脚即可控制步进电机。


用arduino单片机和步进电机制作手掌大的电子琴图44


图 42 驱动器引脚功能


看完步进电机的引脚功能也就不难理解,步进电机驱动器的作用就相当于单片机(Arduino Nano)和步进电机之间的一个桥梁,单片机用来向驱动器发射脉冲信号,当驱动器接收到信号时,会将脉冲信号解释为步进电机线圈的通电顺序,从而驱动电机转动。

知道了A4988驱动的引脚功能后,我们只需要将A4988驱动安装在设计好的电路板上即可,安装时注意方向


用arduino单片机和步进电机制作手掌大的电子琴图45


图 43 未安装步进电机驱动的电路板


步进电机的红-绿-蓝-黑四个引线连接电路板的M1或M2接线柱即可A4988驱动扩展板M1接线柱的STEP、DIR分别对应的Arduino Nano控制器的D3号、D2号数字引脚,M2接线柱的STEP、DIR分别对应的Arduino Nano控制器的D5号、D4号数字引脚


用arduino单片机和步进电机制作手掌大的电子琴图46


图 44 步进电机驱动安装在电路板中


掌握了步进电机、A4988驱动的工作原理,我们就可以开始编写程序了除了步进电机的驱动以外,本次我们还会用到电位器和轻触开关,我们先来了解轻触开关的使用方法

按键的使用


本次步进电机电子琴所使用的轻触开关是典型的数字信号,我们只需要知道轻触开关按下和弹起的状态值即可来弹奏音乐我们在编程环境中输入如下程序

voidsetup() {    Serial.begin(9600);}voidloop() {  Serial.println(digitalRead(6));//串口打印6号数字引脚的数值  delay(1000);}


程序下载后,打开串口监视器即可看到如下测试效果


用arduino单片机和步进电机制作手掌大的电子琴图47


图 45 串口打印测试结果


当轻触开关按下时,输出的状态值为1,松开后的输出值为0知道一个轻触开关的状态值,那么剩余的6个轻触开关也是同样的工作原理,这样我们就可以通过检测7个轻触开关的状态来弹奏音乐了

电位器的使用


掌握了琴键的弹奏方法,下面我们学习如何通过电位器来调节音调,本次步进电机电子琴所使用的电位器是典型的模拟信号,我们需要将模拟信号划分几个区间,用来调节不同的音调

我们在编程环境中输入如下程序来测试一下电位器的数值范围

voidsetup() {    Serial.begin(9600);}voidloop() {  Serial.println(analogRead(A0));//串口打印模拟引脚A0端口的数值  delay(1000);}


程序下载后,打开串口监视器即可看到如下测试效果


用arduino单片机和步进电机制作手掌大的电子琴图48


图 46 串口打印电位器的数值


从上图的结果中可以看出,电位器旋钮的数值范围是0-1023,假如我们需要5种不同的音调,我们就需要将0-1023的数值范围均分成五份,在不同的区间档位下按下按键就可以发出不同的声音。关于钢琴的各种音调(其实真正的学名叫音高)对应的频率,我们可以参考下图,这次我们取O3-O7五种音高

用arduino单片机和步进电机制作手掌大的电子琴图49


图 47 钢琴的音高与频率对照表


当音高确定后,就需要将电位器的数值与五种音高对应起来,实现的方法有两种,第一种方法是将数值范围缩小250倍,代码如下图

voidsetup() {    Serial.begin(9600);}voidloop() {  Serial.println(analogRead(A0)/250);//串口打印模拟引脚A0端口缩小范围后的数值  delay(1000);}


第二种方法是使用map映射函数,将电位器的数值范围映射到0至4的范围,代码如下


int num;voidsetup(){    Serial.begin(9600);}voidloop(){  num = map(analogRead(A0),0,1023,0,4);  Serial.println(num);//串口打印模拟引脚A0端口映射范围后的数值  delay(1000);}


用arduino单片机和步进电机制作手掌大的电子琴图50


图 48 电位器数值映射后的结果


我们还可以将O3至O7音高对应的频率的存放在一个数组中方便索引调用,这样就可以通过电位器的档位调节来切换不同的音调了,除此之外配合数组使用的还有一个结构体,代码如下

  1. <div>typedefstruct {float xfr;}MUSIC;//音高与频率#define PITCHES_LENGTH 35const MUSIC pitches[PITCHES_LENGTH] PROGMEM = {130.813,//O3146.832,164.814,174.614,195.998,220.000,246.942,261.626,//O4293.665,329.629,349.228,391.995,440.000,493.883,523.251,//O5587.330,659.255,698.456,783.991,880.000,987.767,1046.502,//O61174.659,1318.520,1396.913,1567.982,1760.000,1975.533,</div><div>
  2. </div><div>2093.004,//O72349.318,2637.020,2793.826,3135.437,3520.000,3951.066,};</div>
复制代码



当我们将电位器的数值范围与音高一一对应后,接下来就是最关键的步进电机发出声音了


步进电机发音


如何才能做到使用步进电机来发生出声音呢?我们知道声音是由物体的震动产生的,震动的频率越高,对应的音调就越高。其实步进电机之所以能够转动也是因为响应了不同的频率

关于步进电机发声的过程可以这样理解,单片机向步进电机驱动器发射一个脉冲,步进电机就会旋转一定的角度,这个角度就是步距角,单片机不停的发送脉冲,步进电机就不停的转动,脉冲频率越高,电机转动的速度就会越快,那步进电机是如何发出多来咪发索拉西的音调呢?步进电机的发音既然与频率有关,我们先来看一下C调音符与频率的对照表

用arduino单片机和步进电机制作手掌大的电子琴图51


图 49 C调音符与频率对照表


从C调音符对应的频率表格中,我们可以知道,哆对应的频率是523Hz,也就是每秒震动523次,对应到步进电机,我们需要每秒向步进电机驱动器发送523个脉冲,每个脉冲所用的时间就是1/523秒。单片机发送一个高电平和一个低电平为一个脉冲,这里的高电平和低电平持续时间之和正好是1/523秒。那么如果这个高低电平的持续时间改变,对应的频率就会改变,这样一来,我们只需要修改高低电平持续的时间即可切换不同的脉冲频率那么如何才能准确地计算出每个频率对应的时间呢?这里我们就需要用到单片机的定时器了。程序设计的思路是使用单片机的定时器按照一定的频率(也就是时间间隔)进行中断。比如我们利用定时器以60000Hz的速度中断。假如我们要在引脚2产生30Hz的脉冲方波。可以用一个变量来计数。变量每数到60000/30=2000时,就会产生一个30Hz的方波。如果要为更多的步进电机发送脉冲信号,用更多的变量去计数就可以了。这里有的朋友可能会有疑问,频率设置为什么是60000Hz。我们使用定时器来产生步进电机的频率时,如果要产生的频率和定时器中断的频率很接近,就会产生很大的误差,控制步进电机发生的频率最大不会超过4000Hz,经过测试定时器的频率设定为60000Hz时所发出的音调基本符合视听效果了解了定时器发出脉冲频率的基本原理后,接下来我们学习单片机操作定时器的方法


定时器基本操作方法



本次使用的Arduino Nano单片机使用的是atmega328p的芯片。一共有三个定时器:定时器0(8位)、定时器1(16位)、定时器2(8位)。

delay()、millis()、Serial这些官方提供的库函数或者功能依赖于定时器0,所以本次作品我们不能使用定时器0。这里我们选择定时器2,当然也可以用定时器1。

Arduino定时器设置步骤:

  • 设置定时器初值,定时时间;
  • 设置定时器匹配模式;
  • 设置预分频模式,与定时时间有关。

Arduino定时器的匹配模式有普通模式、CTC模式、快速PWM模式、相位可调PWM模式。本次作品采用CTC模式,即用于输出50%占空比的方波信号。每个定时器都有一个计数器,在计数器的每个时钟周期递增。当计数器达到存储在寄存器中的指定值时触发CTC定时器中断。一旦定时器的计数器达到该值,它将在定时器时钟的下一个定时器上清零(复位为零),然后它将继续再次计数,如此循环。通过选择比较匹配值并设置定时器递增计数器的速度,就可以控制定时器中断的频率


预分频系数与比较匹配器



Arduino时钟以16MHz运行。计数器的一个刻度值表示1 / 16000000秒(~63ns),跑完1s需要计数值16000000。

1、Timer0和timer2是8位定时器,可以存储最大计数器值255。2、Timer1是一个16位定时器,可以存储最大计数器值65535。

一旦计数器达到其最大值,它将回到零(这称为溢出)。因此,需要对时钟频率进行分频处理,即预分频器。通过预分频器控制定时计数器的增量速度。

预分频器与定时器的计数速度如下:

定时器速度(Hz) = Arduino时钟速度(16MHz) / 预分频器系数因此,1预分频器将以16MHz递增计数器,8预分频器将在2MHz递增,64预分频器= 250kHz,依此类推。

本次我们设置定时器为64预分频,中断频率为60000Hz,在定时器最大频率范围内


定时器的基本指令


  1. #define FRQ_TIMER2 (60000) //定时器2溢出速度TIMSK2 = _BV(OCIE2A);//开启定时器2中断TIMSK2 = 0;//关闭定时器2中断TCCR2A = _BV(WGM21);//CTC 模式 用于输出50%占空比的方波信号TCCR2B = _BV(CS22);//64分频TCNT2 = 0;//定时器2 计数器寄存器清空OCR2A = 1;//比较寄存器设置为1
复制代码


对定时器的基本指令有一定了解后,我们来看一下定时器计数的方法,通过修改计数值就可以发送不同的频率,代码如下


定时器计数


  1. int  xFrequency = 0;//方波频率变量int  xCounter = 0;//计数变量ISR(TIMER2_COMPA_vect) {if (xFrequency != 0)    {if (++xCounter>= (xFrequency))        {            xCounter = 0;if (bitRead(PORTD, xMOTOR)) //将数值中读取bit(位)            {                bitClear(PORTD, xMOTOR);//将数值的某一位清空为0            }else            {                bitSet(PORTD, xMOTOR); //将数值的某一位设置为0            }        }    }}
复制代码



学会了定时器产生脉冲方波的方法,下面我们还需要对步进电机进行控制,控制步进电机需要对单片机的引脚有一定了解,下面是Arduino Nano单片机所用芯片的引脚图,本次我们需要快速的给外部设备提供中断信号,需要使用PCINT的引脚编号进行编程,而不是常用的Arduino PIN引脚(棕色图标)

用arduino单片机和步进电机制作手掌大的电子琴图52


图 50 ATMEGA328芯片引脚定义


比如,本次我们将步进电机接入电路板的M1接线柱上,那么电路板中对应的使能引脚ENABLE为D13(PCINT5),步进引脚STEP是D3(PCINT19),方向引脚DIR是D2(PCINT18);如果采用PCINT编号设置方法如下

  1. #define ENABLE PCINT5  //使能引脚#define xMOTOR PCINT19  //步进引脚#define xDIR PCINT18   //方向引脚DDRB = _BV(ENABLE);//设置使能引脚DDRD = _BV(xMOTOR) | _BV(xDIR) ;
复制代码



琴键检测


前面我们已经学会了琴键和电位器的使用,现在我们在程序中设置当检测到七个琴键按下后对应发出不同的频率,不同频率的时间由下面的公式计算得出,xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[0+num*7])

FRQ_TIMER2为定时器的中断频率,pgm_read_float(&pitches[0+num*7])为不同音高对应的频率,两者相除就是发送该方波脉冲需要持续的时间


代码如下


  1. <div>#define FRQ_TIMER2 (60000) //定时器2溢出速度voidloop() {</div><div>
  2. </div><div>num = map(analogRead(A0),0,1023,0,4);if((digitalRead(12) || digitalRead(11)) || (digitalRead(10) || (digitalRead(9) || (digitalRead(8) || (digitalRead(7) || digitalRead(6)))))) {TIMSK2 = _BV(OCIE2A);//开启定时器2中断if(digitalRead(12)) {xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[0+num*7]);}if(digitalRead(11)) {xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[1+num*7]);}if(digitalRead(10)) {xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[2+num*7]);}if(digitalRead(9)) {xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[3+num*7]);}if(digitalRead(8)) {xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[4+num*7]);}if(digitalRead(7)) {xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[5+num*7]);}if(digitalRead(6)) {xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[6+num*7]);}}else {TIMSK2 = 0;//关闭定时器2中断}}</div>
复制代码


完整代码



最后,附上步进电机电子琴的完整代码


  1. <div>typedefstruct </div><div>{float xfr;}MUSIC;</div><div>//音高与频率</div><div>#define PITCHES_LENGTH 35</div><div>const MUSIC pitches[PITCHES_LENGTH] PROGMEM = {</div><div>130.813,//O3146.832,164.814,174.614,195.998,220.000,246.942,261.626,//O4293.665,329.629,349.228,391.995,440.000,493.883,523.251,//O5587.330,659.255,698.456,783.991,880.000,987.767,1046.502,//O61174.659,1318.520,1396.913,1567.982,1760.000,1975.533,</div><div>
  2. </div><div>2093.004,//O72349.318,2637.020,2793.826,3135.437,3520.000,3951.066,};</div><div>#define FRQ_TIMER2 (60000) //定时器2溢出速度</div><div>int  xFrequency = 0;//方波频率变量</div><div>int xCounter = 0;//计数变量</div><div>int num;  //音调变量</div><div>#define ENABLE PCINT5  //使能引脚</div><div>#define xMOTOR PCINT19  //步进引脚</div><div>#define xDIR PCINT18   //方向引脚</div><div>voidsetup()</div><div>{    TCCR2A = _BV(WGM21);//CTC 模式 用于输出50%占空比的方波信号    </div><div>TCCR2B = _BV(CS22);//64分频    </div><div>TCNT2 = 0;//定时器2 计数器寄存器清空    </div><div>OCR2A = 1;//比较寄存器设置为1    TIMSK2 = _BV(OCIE2A);//开启定时器2中断    </div><div>DDRB = _BV(ENABLE);//设置使能引脚    </div><div>DDRD = _BV(xMOTOR) | _BV(xDIR) ;   </div><div> PORTD = 0;    </div><div>Serial.begin(9600);}voidloop(){</div><div>
  3. </div><div>  num = map(analogRead(A0),0,1023,0,4);</div><div>if ((digitalRead(12) || digitalRead(11)) || (digitalRead(10) || (digitalRead(9) || (digitalRead(8) || (digitalRead(7) || digitalRead(6)))))) </div><div>{    TIMSK2 = _BV(OCIE2A);//开启定时器2中断</div><div>if (digitalRead(12)) {      xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[0+num*7]);      </div><div>Serial.println(xFrequency);    }</div><div>if (digitalRead(11))</div><div> {      xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[1+num*7]);    }</div><div>if (digitalRead(10)) {      xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[2+num*7]);    }</div><div>if (digitalRead(9)) {      xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[3+num*7]);    }</div><div>if (digitalRead(8)) {      xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[4+num*7]);    }</div><div>if (digitalRead(7)) {      xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[5+num*7]);    }</div><div>if (digitalRead(6)) {      xFrequency = FRQ_TIMER2/pgm_read_float(&pitches[6+num*7]);    }  } </div><div>else {    TIMSK2 = 0;//关闭定时器2中断  }}</div><div>ISR(TIMER2_COMPA_vect) {</div><div>
  4. </div><div>if (xFrequency != 0)    {if (++xCounter>= (xFrequency))       </div><div> {            xCounter = 0;</div><div>
  5. </div><div>if (bitRead(PORTD, xMOTOR))            </div><div>{                bitClear(PORTD, xMOTOR);            }</div><div>else           </div><div> {                bitSet(PORTD, xMOTOR);            }        }    }}</div>
复制代码



至此,步进电机电子琴就制作完成了

#总结#  

在本次的步进电机琴作品中,我们学会了对Arduino寄存器的部分编程方法,知道了使用定时器提高程序的运行速度的技巧,掌握了在轻触开关中加入上拉电阻保持信号稳定的方法,学会了使用电位器调节音调的方法,通过了解这些基础的知识技能,就可以轻松的增加更多的步进电机,理论上步进电机越多,可以演奏的音乐就更丰富,感兴趣的朋友可以去尝试一下哦,期待你的精彩创意

       以上就是本次分享的全部内容了造物让生活更美好,我们下期再见


用arduino单片机和步进电机制作手掌大的电子琴图53



qw54.jpg (95.62 KB, 下载次数: 7376)

Arduino单片机+步进电机 · 制作手掌大的电子琴_image_3.webp

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(16)
帽子
帽子
牛啊,生活中发现创意哈哈
贺h
贺h
做得外观很漂亮,有才华
ling.09
ling.09
好厉害呀
Lb0sihNKI9NJ
Lb0sihNKI9NJ
看起来还可爱
俺是胡胡
俺是胡胡
厉害哦
俺是胡胡
俺是胡胡
陈子涵
陈子涵
666666666666666
盐焗海盐
盐焗海盐
6666666666666
水晶
水晶
66666666666666666666666666
水晶
水晶
66666666666666666666666666666
DI玩
DI玩
旺仔爸爸的帖子,总是细致到极致!
盐焗海盐
盐焗海盐
评论内容
水晶
水晶
6666666666666666
水晶
水晶
666666666666666
诩
不错不错,从生活中选材,牛批!
步进电机我家有一个,改天弄弄看~
yoyojacky
yoyojacky
哇塞,做的真不错! 很有朋克钢琴的感觉啊!哈哈
- 没有更多了 -