Съдържание:

Вълшебен бутон 4k: безжичното дистанционно управление 20USD BMPCC 4k (или 6k): 4 стъпки (със снимки)
Вълшебен бутон 4k: безжичното дистанционно управление 20USD BMPCC 4k (или 6k): 4 стъпки (със снимки)

Видео: Вълшебен бутон 4k: безжичното дистанционно управление 20USD BMPCC 4k (или 6k): 4 стъпки (със снимки)

Видео: Вълшебен бутон 4k: безжичното дистанционно управление 20USD BMPCC 4k (или 6k): 4 стъпки (със снимки)
Видео: ЗАПРЕЩЁННЫЕ ТОВАРЫ с ALIEXPRESS 2023 ШТРАФ и ТЮРЬМА ЛЕГКО! 2024, Ноември
Anonim
Image
Image

Много хора ме помолиха да споделя някои подробности за моя безжичен контролер за BMPCC4k. Повечето въпроси бяха относно контрола на bluetooth, така че ще спомена няколко подробности за това. Предполагам, че сте запознати със средата ESP32 Arduino.

Тази версия на дистанционното може да контролира записа, фокуса и блендата на камерата чрез Bluetooth. Разгледайте видеото. Съвсем лесно е да добавите още функции за управление съгласно ръководството за управление на bluetooth на BMPCC4k. По принцип всичко в камерата може да се контролира, доколкото съм виждал.

Би било лесна стъпка да добавите LIDAR модул за измерване на разстоянието на обект, така че да можете да получите някаква система за автоматично фокусиране … Въпреки че е съмнително дали можете да получите достатъчно точен фокус върху определени области, като очите и т.н.

АКТУАЛИЗАЦИЯ 2020: Направих версия 3.0. Той се основава на свободно въртящо се колело, използващо магнитен енкодер. Той също така се свързва с моя двигател за следване на фокус, който по същество се превръща във второ Bluetooth устройство (ESP32 поддържа множество Bluetooth връзки). Новото видео демонстрира това.

Ако искате да поръчате версия 3, моля, разгледайте уеб сайта на MagicButton

Консумативи

Всеки ESP32 модул с wifi и bluetooth. Използвах TTGO micro32, защото е малък:

Колело за фокусиране, всеки потенциометър би бил подходящ. Използвах следното, защото е мъничко: https://www.aliexpress.com/item/32963061806.html? S… Този вид има твърди спирки в горната и долната граница. В бъдеща версия ще използвам въртящ се енкодер. По този начин фокусът или блендата не "скачат" към текущата настройка на колелото, когато влизам в режим.

Бутон за запис/режим. Използвах следното: https://www.aliexpress.com/item/32806223591.html? S…

Други стандартни компоненти като резистори, капачки, … (вижте схемата)

Стъпка 1: Кодът

Използвам wifi възможностите на ESP32, за да се свържа или с известна мрежа в режим AP, или, когато съм на полето, тя се превръща в станция (STA), към която мога да се свържа. По този начин мога да конфигурирам модула. Няма да навлизам в подробности за секцията wifi/уеб страница, може да добавя това на по -късен етап.

ESP32 се свързва с камерата и става Bluetooth LE клиент. Bluetooth кодът, включен в ESP32 рамката на Arduino, не работи с BMPCC4k. Wakwak-koba го поправи за нас. Благодаря ти Wakwak-koba! Използвах библиотеката BLE от тук:

github.com/wakwak-koba/arduino-esp32

Независимо от това тази версия на BLE lib все още се разработва и най -новата версия на BLEUUID.cpp изглежда не работи в този момент, така че вземете по -ранната „проверена“версия на този файл.

За останалата част повечето от моя bluetooth код са много според примерите за BLE, включени в рамката на Arduino:

Някои BLE UUID и променливи определят:

статичен BLEUUID BlackMagic ("00001800-0000-1000-8000-00805f9b34fb");

статичен BLEUUID ControlserviceUUID ("291D567A-6D75-11E6-8B77-86F30CA893D3"); статичен BLEUUID DevInfoServiceControlUUID ("180A"); статичен BLEUUID ControlcharUUID ("5DD3465F-1AEE-4299-8493-D2ECA2F8E1BB"); статичен BLEUUID NotifcharUUID ("B864E140-76A0-416A-BF30-5876504537D9"); статичен BLEUUID ClientNamecharUUID ("FFAC0C52-C9FB-41A0-B063-CC76282EB89C"); статичен BLEUUID CamModelcharUUID ("2A24"); статичен BLEScan *pBLEScan = BLEDevice:: getScan (); статичен BLEAddress *pServerAddress; статичен BLEAdvertisedDevice* myDevice; статичен BLERemoteCharacteristic *pControlCharacteristic; статичен BLERemoteCharacteristic *pNotifCharacteristic; статично логическо doConnect = 0; статично логическо свързване = 0; сканиране на volatilebool = 0; volatileuint32_t pinCode;

Сканирането и основният цикъл:

клас MyAdvertisedDeviceCallbacks: обществен BLEAdvertisedDeviceCallbacks {

void onResult (BLEAdvertisedDevice advertisedDevice) {Serial.print ("Намерено рекламирано устройство на BLE:"); Serial.println (advertisedDevice.toString (). C_str ()); if (advertisedDevice.haveServiceUUID () && advertisedDevice.getServiceUUID (). е равно (BlackMagic)) {Serial.print ("Намерено е нашето устройство!"); advertisedDevice.getScan ()-> stop (); myDevice = нов BLEAdvertisedDevice (advertisedDevice); doConnect = вярно; }}}; static void scanCompleteCB (BLEScanResults scanResults) {Serial.println ("сканирането е извършено"); сканиране = невярно; } void loop (void) {if (! connected && ((uint32_t) (millis () - Timer)> BLE_RESCAN_TIME || (! сканиране))) {Serial.println ("сканиране …"); сканиране = вярно; pBLEScan-> старт (BLE_SCAN_TIME, scanCompleteCB); Таймер = милис (); } if (doConnect == true) {if (connectToServer ()) {Serial.println ("Сега сме свързани с BLE сървъра."); свързан = вярно; } else {Serial.println ("Не успяхме да се свържем със сървъра; няма да направим нищо повече."); } doConnect = false; }}

Свързване към камерата:

bool connectToServer () {

Serial.print ("Формиране на връзка с"); Serial.println (myDevice-> getAddress (). ToString (). C_str ()); BLEDevice:: setEncryptionLevel (ESP_BLE_SEC_ENCRYPT); BLEDevice:: setSecurityCallbacks (нов MySecurity ()); BLESecurity *pSecurity = нов BLESecurity (); pSecurity-> setKeySize (); pSecurity-> setAuthenticationMode (ESP_LE_AUTH_REQ_SC_MITM_BOND); pSecurity-> setCapability (ESP_IO_CAP_IN); pSecurity-> setRespEncryptionKey (ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK); BLEClient *pClient = BLEDevice:: createClient (); pClient-> setClientCallbacks (нов MyClientCallback ()); pClient-> свързване (myDevice); Serial.println (" - Свързан със сървър"); BLEDevice:: setMTU (BLEDevice:: getMTU ()); // ПОЛУЧАВАМЕ МОДЕЛ НА КАМЕРА BLERemoteService *pRemoteService = pClient-> getService (DevInfoServiceControlUUID); if (pRemoteService == nullptr) {Serial.print (" - Неуспешно получаване на информация за устройството"); Serial.println (DevInfoServiceControlUUID.toString (). C_str ()); да се провали; } Serial.println (" - Четене на информация за устройството"); // Получаване на препратка към характеристиката в услугата на отдалечения BLE сървър. BLERemoteCharacteristic *pRemoteCamModelCharacteristic = pRemoteService-> getCharacteristic (CamModelcharUUID); if (pRemoteCamModelCharacteristic == nullptr) {Serial.print (" - Неуспешно намиране на модел на камерата"); Serial.println (CamModelcharUUID.toString (). C_str ()); да се провали; } // Прочетете стойността на характеристиката. std:: string value = pRemoteCamModelCharacteristic-> readValue (); Serial.print ("Камерата е"); Serial.println (value.c_str ()); if (CamModel! = value.c_str ()) {Serial.print (" - Камерата не е BMPCC4k"); да се провали; } // ПОЛУЧИ КОНТРОЛ pRemoteService = pClient-> getService (ControlserviceUUID); if (pRemoteService == nullptr) {Serial.print (" - Неуспешно получаване на услуга за камера"); Serial.println (ControlserviceUUID.toString (). C_str ()); да се провали; } BLERemoteCharacteristic *pRemoteClientNameCharacteristic = pRemoteService-> getCharacteristic (ClientNamecharUUID); if (pRemoteClientNameCharacteristic! = nullptr) {pRemoteClientNameCharacteristic-> writeValue (MyName.c_str (), MyName.length ()); } pControlCharacteristic = pRemoteService-> getCharacteristic (ControlcharUUID); if (pControlCharacteristic == nullptr) {Serial.print (" - Неуспешно получаване на контролна характеристика"); Serial.println (ControlcharUUID.toString (). C_str ()); да се провали; } pNotifCharacteristic = pRemoteService-> getCharacteristic (NotifcharUUID); if (pNotifCharacteristic! = nullptr) // && pNotifCharacteristic-> canIndicate ()) {Serial.println (" - абониране за известие"); const uint8_t indicationOn = {0x2, 0x0}; pNotifCharacteristic-> registerForNotify (notifyCallback, false); pNotifCharacteristic-> getDescriptor (BLEUUID ((uint16_t) 0x2902))-> writeValue ((uint8_t*) индикацияOn, 2, true); } return true; неуспех: pClient-> прекъсване (); return false; }

Свързаното/прекъснатото обратно повикване:

class MyClientCallback: обществен BLEClientCallbacks {

void onConnect (BLEClient *pclient) {Serial.println ("Ние сме свързани."); } void onDisconnect (BLEClient *pclient) {connected = false; pclient-> прекъсване (); Serial.println ("Прекъснахме връзката."); }};

Частта с пин кода:

В текущата ми версия мога да въведа пинкода чрез уеб интерфейса, но това са подробности за wifi/уеб страница, които мога да добавя по -късно.

клас MySecurity: обществени BLESecurityCallbacks

{uint32_t onPassKeyRequest () {Serial.println ("- МОЛЯ ВЪВЕДЕТЕ 6 ЦИФРОВ ПИН (край с ENTER):"); pinCode = 0; char ch; do {while (! Serial.available ()) {delay (1); } ch = Serial.read (); if (ch> = '0' && ch <= '9') {pinCode = pinCode *10+ (ch -'0 '); Serial.print (ch); }} while ((ch! = '\ n')); връщане на pinCode; } void onPassKeyNotify (uint32_t pass_key) {ESP_LOGE (LOG_TAG, "Номер за известие на ключа за достъп:%d", pass_key); } bool onConfirmPIN (uint32_t pass_key) {ESP_LOGI (LOG_TAG, "Ключът за достъп YES/NO номер:%d", pass_key); vTaskDelay (5000); връщане; } bool onSecurityRequest () {ESP_LOGI (LOG_TAG, "Заявка за сигурност"); връщане; } void onAuthenticationComplete (esp_ble_auth_cmpl_t auth_cmpl) {Serial.print ("двойка статус ="); Serial.println (auth_cmpl.success); }};

BLE известие:

Камерата уведомява своите BLE клиенти за всяка промяна на камерата, включително когато камерата започне и спре записа. Този код превключва моя светодиод, когато стартира/спира записа.

static void notifyCallback (BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t*pData, size_t дължина, bool isNotify) {// BMPCC4k BLE формат на съобщението: // rec on е 255 9 0 0 10 1 1 2 2 0 64 0 2 // rec off е 255 9 0 0 10 1 1 2 0 0 64 0 2if (length == 13 && pData [0] == 255 && pData [1] == 9 && pData [4] == 10 && pData [5] == 1) {if (pData [8] == 0) { recstatus = 0; } ако (pData [8] == 2) {recstatus = 1; }}}

Стъпка 2: Кодът, част 2

Това е частта, която всъщност изпраща командите към камерата.

Запис:

uint8_t запис = {255, 9, 0, 0, 10, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 0 = OFF, 2 = ON, [8] void Record (булево RecOn) {if (! RecOn) запис [8] = 0; else запис [8] = 2; pControlCharacteristic-> writeValue ((uint8_t*) запис, 16, вярно); }

Фокусиране:

Камерата очаква 11 -битово число, вариращо от близки до далечни фокуси. Съветвам ви да поставите филтър върху стойността на ADC, в противен случай фокусът може да бъде нервно трептене.

uint8_t focus = {255, 6, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0}; // 0.0… 1.0, 11bit, [8] = LSB, [9] = MSBvoid Focus (uint16_t val) {// преминаване от 12 -битова стойност на ADC към 11 -битова стойност на фокуса фокус [8] = (uint8_t) (((val> > 1) & 0xFF)); фокус [9] = (uint8_t) (((val >> 1) & 0xFF00) >> 8); pControlCharacteristic-> writeValue ((uint8_t*) фокус, 12, вярно); }

Бленда:

Камерата очаква 11 -битово число, вариращо от ниска до висока стойност на блендата. Съветвам ви да поставите филтър на стойността на ADC, в противен случай стойността на блендата може да е нервно трептене.

uint8_t бленда = {255, 6, 0, 0, 0, 3, 128, 0, 0, 0, 0, 0}; // 0.0… 1.0, [8] = LSB, [9] = MSBvoid Aperture (uint16_t val) {// преминаване от 12 -битова ADC стойност към 11 -битова стойност на блендата aperture [8] = (uint8_t) (((val >> 1) & 0xFF)); бленда [9] = (uint8_t) (((val >> 1) & 0xFF00) >> 8); pControlCharacteristic-> writeValue ((uint8_t*) бленда, 12, вярно); }

Стъпка 3: Веригата

Веригата
Веригата

Прикачих PDF файла на моята схема. Прикачени са и някои снимки на печатната платка.

Платката се захранва с микро USB.

След като получих печатната платка, реших, че искам да управлявам RGB светодиод, затова свързах последователно два WS2812B към изхода "Button Led" (за това бяха нужни някои кабели на платката). ПХБ бяха 8USD с OSHPark.com.

Можете да видите още някои връзки на печатната платка, като "adc", които не използвам и които бяха премахнати от приложените схеми. Планът беше да използвам външно колело за фокусиране в миналото, но в момента съм напълно доволен от колелото на малкия палец.

Стъпка 4: Заключение

Надявам се това да е помогнало.

Имам предвид някои бъдещи актуализации, като например използване на въртящ се енкодер без трудно спиране. Това ще изисква контролерът да получи текущата стойност на фокуса или блендата от камерата и да продължи оттам. Вероятно функцията "notifyCallback" трябва да бъде актуализирана за това.

Печатната платка се нуждае от актуализация, за да осигури правилно сигналите за WS2812B RGB светодиодите.

Прекарах много (много) време в създаването на тази работа, особено в частта BLE. Ако това ви помогна и искате да ми купите питие, това е много оценено:) Това е връзка за дарение в Paypal:

Препоръчано: