Last active
October 23, 2025 17:31
-
-
Save acidsound/eebf85d2a86033d73c654b05a8d517d6 to your computer and use it in GitHub Desktop.
BLE MIDI 를 검색하고 연결. u8g2 라이브러리를 사용하여 정보를 화면에 뿌려준다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <Arduino.h> | |
| #include <NimBLEDevice.h> | |
| #include <U8g2lib.h> | |
| // BLE MIDI 서비스 고유 UUID | |
| static BLEUUID midiServiceUUID("03B80E5A-EDE8-4B33-A751-6CE34EC4C700"); | |
| // 스캔 후 찾은 장치 포인터 | |
| BLEAdvertisedDevice* myDevice = nullptr; | |
| bool connected = false; | |
| std::string connectedDeviceName; | |
| // there is no 72x40 constructor in u8g2 hence the 72x40 screen is mapped in the middle of the 132x64 pixel buffer of the SSD1306 controller | |
| U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, 6, 5); | |
| int width = 72; | |
| int height = 40; | |
| int xOffset = 30; // = (132-w)/2 | |
| int yOffset = 12; // = (64-h)/2 | |
| unsigned long lastMarqMillis = 0; | |
| int marqPos = 0; | |
| void updateU8G2(const char* name) { | |
| u8g2.clearBuffer(); | |
| u8g2.drawFrame(xOffset - 2, yOffset + 12, width, height); | |
| u8g2.setCursor(xOffset, yOffset + 48); | |
| u8g2.printf("%s", "@acidsound"); | |
| u8g2.setCursor(xOffset, yOffset + 23); | |
| u8g2.println("::MIDI FROM"); | |
| size_t nameLen = strlen(name); | |
| const int displayLen = 11; | |
| char displayStr[displayLen + 1]; // +1 for null terminator | |
| if (nameLen <= displayLen) { | |
| // 문자열이 11자 이하면 그대로 표시 | |
| strncpy(displayStr, name, displayLen); | |
| displayStr[nameLen] = '\0'; | |
| } else { | |
| // marquee 효과: 맨 끝과 맨 앞 사이 공백 1칸 삽입 | |
| int scrollLen = nameLen + 1; // 공백 한 칸 추가한 길이 | |
| for (int i = 0; i < displayLen; i++) { | |
| int idx = (marqPos + i) % scrollLen; | |
| if (idx == nameLen) { | |
| displayStr[i] = ' '; // 공백 삽입 | |
| } else { | |
| displayStr[i] = name[idx]; | |
| } | |
| } | |
| displayStr[displayLen] = '\0'; | |
| } | |
| u8g2.setCursor(xOffset, yOffset + 35); | |
| u8g2.printf("%s", displayStr); | |
| u8g2.sendBuffer(); | |
| } | |
| // 스캔 결과를 처리할 콜백 클래스 | |
| class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { | |
| void onResult(BLEAdvertisedDevice* advertisedDevice) override { | |
| if (advertisedDevice->isAdvertisingService(midiServiceUUID)) { | |
| Serial.print("Found BLE MIDI Device: "); | |
| Serial.print(advertisedDevice->getName().c_str()); | |
| Serial.print(" (Address: "); | |
| Serial.print(advertisedDevice->getAddress().toString().c_str()); | |
| Serial.println(")"); | |
| connectedDeviceName = advertisedDevice->getName(); | |
| Serial.printf("update device: %s", connectedDeviceName.c_str()); | |
| Serial.println(""); | |
| if (myDevice == nullptr) { | |
| Serial.println("Connecting device"); | |
| myDevice = new BLEAdvertisedDevice(*advertisedDevice); | |
| BLEDevice::getScan()->stop(); | |
| } | |
| } | |
| } | |
| }; | |
| void listenBLEMIDI() { | |
| Serial.println("Starting BLE Scan for MIDI Controllers..."); | |
| BLEDevice::init(""); | |
| BLEScan* pBLEScan = BLEDevice::getScan(); | |
| // 디바이스 콜백 등록 | |
| pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); | |
| pBLEScan->setActiveScan(true); | |
| pBLEScan->start(10); | |
| // 스캔 완료 후 myDevice가 설정되었는지 확인 | |
| if (myDevice == nullptr) { | |
| Serial.println("No MIDI device found. Restart and try again."); | |
| return; | |
| } | |
| Serial.println("Attempting to connect to the device..."); | |
| connected = true; | |
| // myDevice 메모리 해제 및 초기화 | |
| // delete myDevice; | |
| // myDevice = nullptr; | |
| } | |
| void setup() { | |
| Serial.begin(115200); | |
| u8g2.begin(); | |
| u8g2.setContrast(255); // set contrast to maximum | |
| u8g2.setBusClock(400000); //400kHz I2C | |
| u8g2.setFont(u8g2_font_6x10_mr); | |
| } | |
| void loop() { | |
| unsigned long currentMillis = millis(); | |
| // marquee 0.4초 간격 타이머 | |
| if (currentMillis - lastMarqMillis >= 400) { | |
| lastMarqMillis = currentMillis; | |
| if (connected && connectedDeviceName.length() > 11) { | |
| marqPos++; | |
| if (marqPos >= connectedDeviceName.length()) { | |
| marqPos = 0; | |
| } | |
| } | |
| } | |
| // 연결이 끊어지면 재연결 시도 | |
| if (myDevice == nullptr) { | |
| updateU8G2("no device"); // 기본 문자열 표시 | |
| } else { | |
| updateU8G2(connectedDeviceName.c_str()); | |
| } | |
| if (!connected) { | |
| Serial.println("Disconnected. Scanning for a new device to connect..."); | |
| listenBLEMIDI(); // 스캔 및 재연결 재시도 | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment