aerobotics

MIDI_Boy

 
Overview

Summary

 

This project mainly uses the ESP32 module as the main control, connects to the mobile phone through the Bluetooth MIDI protocol, and cooperates with the mobile APP (GarageBand, etc.) to implement an electronic keyboard.

 

The rendering is as follows:

MIDI Boy Rendering

 

Demo video

 

None yet



kalimba

 

This design uses the real kalimba as a reference, and 鼠标按键uses the metal shrapnel shown in the figure below instead of the kalimba 蜂鸣器as the generating component.

 

mouse buttons

 

buzzer

 

Simply using a buzzer as a sound-generating component may not perform very well. Therefore, this project uses the ESP32 module as the main control, uses its Bluetooth function to connect to the mobile phone, and enhances its expressiveness through interaction with the mobile phone.

 

ESP32 module

 

ESP32 is a powerful IoT chip that can support WiFi and Bluetooth functions at the same time. It has 20+ available GPIOs and a running frequency of up to 240MHz. It can be developed using methods such as C语言, Ardiuno, etc.MicroPython



In order to simulate the feel of a real kalimba, before designing the hardware, we first measured the dimensions of the 17-key kalimba shown in the picture above , 尺寸and 键距 finally determined the size of 141mm*88mm and the key spacing of 7.6mm.

In addition to buttons and buzzers, a serial port chip is also used CH340for burning programs, and several WS2812colored lights enhance the music atmosphere.

 

The complete schematic is as follows:

MIDI Boy Schematic
MIDI schematic

PCB layout reference:

Insert image description here

 

In order to pursue aesthetics, all circuits are arranged on the back of the PCB board.

In addition, for the sake of beauty, the USB interface is placed below the antenna. This design will affect the wireless signal, so please do not imitate it!

 

Hardware open source address:



 

As mentioned earlier, there are many development methods for ESP32. I used the MicroPython development method here. The advantage is that the development environment is relatively simple to set up and the amount of code is not small. The current program is not perfect. The core code is as follows:

 

from machine import Pin, Timer
from time import sleep_ms
import ubluetooth
from esp32 import raw_temperature

class BLE():

    def __init__(self, name):

        self.name = name
        self.ble = ubluetooth.BLE()
        self.ble.active(True)

        self.led = Pin(14, Pin.OUT)
        self.timer1 = Timer(0)
        self.timer2 = Timer(1)

        self.disconnected()
        self.ble.irq(self.ble_irq)
        self.register()
        self.advertiser()
        self.isConnected = False

    def connected(self):

        self.timer1.deinit()
        self.timer2.deinit()

    def disconnected(self):

        self.timer1.init(period=1000, mode=Timer.PERIODIC, callback=lambda t: self.led(1))
        sleep_ms(200)
        self.timer2.init(period=1000, mode=Timer.PERIODIC, callback=lambda t: self.led(0))

    def ble_irq(self, event, data): # 蓝牙事件处理

        if event == 1: # Central disconnected
          self.isConnected = True
          self.connected()
          self.led(1)

        elif event == 2: # Central disconnected
            self.isConnected = False
            self.advertiser()
            self.disconnected()

        elif event == 4: # New message received

            buffer = self.ble.gatts_read(self.midi)
            message = buffer.decode('UTF-8')[:-1]
            print(message)

            if received == 'blue_led':
                blue_led.value(not blue_led.value())

    def register(self): # 注册MIDI蓝牙服务

        MIDI_SERVER_UUID = ubluetooth.UUID('03B80E5A-EDE8-4B33-A751-6CE34EC4C700')
        MIDI_CHAR_UUID   = (ubluetooth.UUID('7772E5DB-3868-4112-A1A9-F2669D106BF3'), 
          ubluetooth.FLAG_READ | ubluetooth.FLAG_WRITE | ubluetooth.FLAG_NOTIFY , )

        BLE_MIDI_SERVER = (MIDI_SERVER_UUID, (MIDI_CHAR_UUID , ) , )
        SERVICES = (BLE_MIDI_SERVER, )

        ((self.midi,), ) = self.ble.gatts_register_services(SERVICES)

    def send(self, data):
      if self.isConnected :
        self.ble.gatts_notify(0, self.midi, data)

    def advertiser(self): # 设置广播及扫描响应数据
        name = bytes(self.name, 'UTF-8')
        self.ble.gap_advertise(100, adv_data = b'x02x01x05' + bytearray((len(name) + 1, 0x09)) + name ,  
          resp_data = b'x11x07x00xC7xC4x4ExE3x6Cx51xA7x33x4BxE8xEdx5Ax0ExB8x03')

ble = BLE("ESP32")

k_d6 = Pin(32, Pin.IN, Pin.PULL_UP)
k_b5 = Pin(33, Pin.IN, Pin.PULL_UP)
k_g5 = Pin(25, Pin.IN, Pin.PULL_UP)
k_e5 = Pin(26, Pin.IN, Pin.PULL_UP)
k_c5 = Pin(27, Pin.IN, Pin.PULL_UP)
k_a4 = Pin(12, Pin.IN, Pin.PULL_UP)
k_f4 = Pin(13, Pin.IN, Pin.PULL_UP)
k_d4 = Pin(15, Pin.IN, Pin.PULL_UP)

k_c4 = Pin(4,  Pin.IN, Pin.PULL_UP)

k_e4 = Pin(16, Pin.IN, Pin.PULL_UP)
k_g4 = Pin(17, Pin.IN, Pin.PULL_UP)
k_b4 = Pin(5,  Pin.IN, Pin.PULL_UP)
k_d5 = Pin(18, Pin.IN, Pin.PULL_UP)
k_f5 = Pin(19, Pin.IN, Pin.PULL_UP)
k_a5 = Pin(21, Pin.IN, Pin.PULL_UP)
k_c6 = Pin(22, Pin.IN, Pin.PULL_UP)
k_e6 = Pin(23, Pin.IN, Pin.PULL_UP)

key_pin_list   = [k_c4,k_d4,k_e4,k_f4,k_g4,k_a4,k_b4,k_c5,k_d5,k_e5,k_f5,k_g5,k_a5,k_b5,k_c6,k_d6,k_e6]
key_name_list  = ['k_c4','k_d4','k_e4','k_f4','k_g4','k_a4','k_b4','k_c5','k_d5','k_e5','k_f5','k_g5','k_a5','k_b5','k_c6','k_d6','k_e6']
key_value_last = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
key_value_now  = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

midi_start = 0x48 #C4键的音高

# 与C4相比的音程查
midi_inve  = [0,2,4,5,7,9,11,12,14,16,17,19,21,23,24,26,28]

while True :

  for i in range(17):
    key_value_now[i] = key_pin_list[i].value()

    if not key_value_last[i] == key_value_now[i] :
      if key_value_now[i] == 0:
        print("on_" + key_name_list[i])
        ble.send(bytearray([0x80, 0x80, 0x90, midi_start + midi_inve[i] , 0x63]))
      else :
        print("off_" + key_name_list[i])
        ble.send(bytearray([0x80, 0x80, 0x80, midi_start + midi_inve[i] , 0x00]))

      key_value_last[i] = key_value_now[i]
      sleep_ms(10)




Insert image description here

 

If you like to change the article, welcome 点赞 评论 收藏 转发!

 

I am Teacher Peng!

参考设计图片
×
 
 
Search Datasheet?

Supported by EEWorld Datasheet

Forum More
Update:2024-11-14 23:13:54

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号