สารบัญ:

Magic Button 4k: 20USD BMPCC 4k (หรือ 6k) รีโมทคอนโทรลไร้สาย: 4 ขั้นตอน (พร้อมรูปภาพ)
Magic Button 4k: 20USD BMPCC 4k (หรือ 6k) รีโมทคอนโทรลไร้สาย: 4 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: Magic Button 4k: 20USD BMPCC 4k (หรือ 6k) รีโมทคอนโทรลไร้สาย: 4 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: Magic Button 4k: 20USD BMPCC 4k (หรือ 6k) รีโมทคอนโทรลไร้สาย: 4 ขั้นตอน (พร้อมรูปภาพ)
วีดีโอ: 7 BMPCC 4K or 6K Tips to Improve your Productions | Blackmagic Pocket Cinema Camera Tips 2024, กรกฎาคม
Anonim
Image
Image

หลายคนขอให้ฉันแชร์รายละเอียดบางอย่างเกี่ยวกับคอนโทรลเลอร์ไร้สายของฉันสำหรับ BMPCC4k คำถามส่วนใหญ่เกี่ยวกับการควบคุมบลูทูธ ดังนั้นฉันจะพูดถึงรายละเอียดบางอย่างเกี่ยวกับเรื่องนี้ ฉันถือว่าคุณคุ้นเคยกับสภาพแวดล้อม ESP32 Arduino

รีโมทรุ่นนี้สามารถควบคุมการบันทึก โฟกัส และรูรับแสงของกล้องผ่านบลูทูธ ดูวิดีโอ ค่อนข้างง่ายในการเพิ่มฟังก์ชันการควบคุมเพิ่มเติมตามคู่มือควบคุมบลูทูธของ BMPCC4k โดยทั่วไปทุกอย่างในกล้องสามารถควบคุมได้ เท่าที่ฉันเคยเห็น

การเพิ่มโมดูล LIDAR จะเป็นขั้นตอนง่ายๆ ในการวัดระยะห่างของวัตถุ คุณจึงสามารถใช้ระบบโฟกัสอัตโนมัติได้… แม้ว่าจะยังมีข้อสงสัยว่าคุณสามารถโฟกัสได้อย่างแม่นยำเพียงพอในพื้นที่เฉพาะ เช่น ดวงตา ฯลฯ หรือไม่…

อัปเดต 2020: ฉันสร้างเวอร์ชัน 3.0 มันขึ้นอยู่กับล้อหมุนฟรีโดยใช้เครื่องเข้ารหัสแม่เหล็ก นอกจากนี้ยังเชื่อมต่อกับมอเตอร์โฟกัสติดตามของฉันซึ่งโดยทั่วไปจะกลายเป็นอุปกรณ์บลูทู ธ ตัวที่สอง (ESP32 รองรับการเชื่อมต่อบลูทู ธ หลายตัว) วิดีโอใหม่นี้แสดงให้เห็น

หากคุณต้องการสั่งซื้อเวอร์ชัน 3 โปรดดูที่เว็บไซต์ MagicButton

เสบียง

โมดูล ESP32 ใด ๆ ที่มี wifi และบลูทู ธ ฉันใช้ TTGO micro32 เพราะมันเล็ก:https://www.banggood.com/LILYGO-TTGO-Micro-32-V2_0…

ล้อโฟกัส โพเทนชิออมิเตอร์แบบใดก็ได้ ฉันใช้สิ่งต่อไปนี้เพราะมันเล็ก: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 รหัสบลูทูธที่รวมอยู่ในกรอบงาน ESP32 ของ Arduino ใช้ไม่ได้กับ BMPCC4k Wakwak-koba ได้แก้ไขให้เรา ขอบคุณ Wakwak-koba! ฉันใช้ห้องสมุด BLE จากที่นี่:

github.com/wakwak-koba/arduino-esp32

อย่างไรก็ตาม BLE lib เวอร์ชันนั้นยังอยู่ระหว่างการพัฒนาและ BLEUUID.cpp เวอร์ชันล่าสุดดูเหมือนจะไม่ทำงานในขณะนี้ ดังนั้นโปรดใช้เวอร์ชัน "ยืนยัน" ก่อนหน้านี้ของไฟล์นี้

สำหรับส่วนที่เหลือรหัสบลูทู ธ ส่วนใหญ่ของฉันมีจำนวนมากตามตัวอย่าง BLE ที่รวมอยู่ในกรอบงาน Arduino:

BLE UUID และตัวแปรบางตัวกำหนด:

BLEUUID BlackMagic แบบคงที่ ("00001800-0000-1000-8000-00805f9b34fb");

คงที่ BLEUUID ControlserviceUUID("291D567A-6D75-11E6-8B77-86F30CA893D3"); คงที่ BLEUUID DevInfoServiceControlUUID ("180A"); ตัวควบคุม BLEUUID แบบคงที่UUID("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; การสแกนโวลาไทล์บูล =0; volatileuint32_t pinCode;

การสแกนและลูปหลัก:

คลาส MyAdvertisedDeviceCallbacks: BLEAdvertisedDeviceCallbacks สาธารณะ{

โมฆะ onResult (BLEAdvertisedDevice AdvertisedDevice) { Serial.print ("พบอุปกรณ์ที่โฆษณา BLE: "); Serial.println(advertisedDevice.toString().c_str()); if (advertisedDevice.haveServiceUUID() && AdvertisedDevice.getServiceUUID().equals(BlackMagic)) { Serial.print("พบอุปกรณ์ของเราแล้ว!"); AdvertisedDevice.getScan()->หยุด(); myDevice = BLEAdvertisedDevice ใหม่ (advertisedDevice); doConnect =จริง; } } }; โมฆะคงที่ scanCompleteCB (BLEScanResults scanResults) { Serial.println ("การสแกนเสร็จสิ้น"); การสแกน = เท็จ; } void loop(เป็นโมฆะ) { if (!connected && ((uint32_t)(millis() - Timer) > BLE_RESCAN_TIME || (!scanning))) { Serial.println("scanning…"); สแกน =จริง; pBLEScan->เริ่ม (BLE_SCAN_TIME, scanCompleteCB); ตัวจับเวลา = มิลลิวินาที (); } if (doConnect ==true) { if (connectToServer()) { Serial.println("เราเชื่อมต่อกับเซิร์ฟเวอร์ BLE แล้ว"); เชื่อมต่อ = จริง; } อื่น { Serial.println ("เราไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ ไม่มีอะไรเพิ่มเติมที่เราจะทำ"); } doConnect = false; } }

การเชื่อมต่อกับกล้อง:

บูล 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()); BLEDevice::setMTU(BLEDevice::getMTU()); // รับโมเดลกล้อง BLERemoteService *pRemoteService = pClient->getService(DevInfoServiceControlUUID); ถ้า (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 ค่า = pRemoteCamModelCharacteristic->readValue(); Serial.print("กล้องคือ"); Serial.println(value.c_str()); if (CamModel != value.c_str()) { Serial.print(" - กล้องไม่ใช่ BMPCC4k"); ไปล้มเหลว; } // รับการควบคุม pRemoteService = pClient->getService(ControlserviceUUID); ถ้า (pRemoteService == nullptr) { Serial.print (" - ไม่สามารถรับบริการกล้องได้"); Serial.println(ControlserviceUUID.toString().c_str()); ไปล้มเหลว; } BLERemoteCharacteristic *pRemoteClientNameCharacteristic = pRemoteService->getCharacteristic(ClientNamecharUUID); ถ้า (pRemoteClientNameCharacteristic != nullptr) { pRemoteClientNameCharacteristic->writeValue (MyName.c_str (), MyName.length ()); } pControlCharacteristic = pRemoteService->getCharacteristic(ControlcharUUID); ถ้า (pControlCharacteristic == nullptr) { Serial.print (" - ล้มเหลวในการรับลักษณะการควบคุม"); Serial.println(ControlcharUUID.toString().c_str()); ไปล้มเหลว; } pNotifCharacteristic = pRemoteService->getCharacteristic(NotifcharUUID); if (pNotifCharacteristic != nullptr) // && pNotifCharacteristic->canIndicate()) { Serial.println (" - สมัครรับการแจ้งเตือน"); const uint8_t indicatorOn = {0x2, 0x0}; pNotifCharacteristic->registerForNotify (แจ้งการโทรกลับเป็นเท็จ); pNotifCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)indicationOn, 2, true); } คืนค่าจริง; ล้มเหลว: pClient->disconnect(); คืนค่าเท็จ; }

การโทรกลับที่เชื่อมต่อ/ตัดการเชื่อมต่อ:

คลาส MyClientCallback: BLEClientCallbacks สาธารณะ{

เป็นโมฆะ onConnect (BLEClient * pclient) { Serial.println ("เราเชื่อมต่อกันแล้ว"); } โมฆะ onDisconnect (BLEClient * pclient) { เชื่อมต่อ = false; pclient->ตัดการเชื่อมต่อ(); Serial.println("เราถูกตัดการเชื่อมต่อ"); } };

ส่วนรหัสพิน:

ในเวอร์ชันปัจจุบันของฉัน ฉันสามารถป้อนรหัสพินผ่านเว็บอินเทอร์เฟซ แต่สิ่งเหล่านี้เป็นรายละเอียด wifi/หน้าเว็บ ซึ่งฉันอาจเพิ่มในภายหลัง

คลาส MySecurity: BLESecurityCallbacks สาธารณะ

{ uint32_t onPassKeyRequest() { Serial.println("- โปรดป้อน PIN 6 หลัก (ลงท้ายด้วย ENTER): "); รหัสพิน =0; ถ่าน ch; ทำ { ในขณะที่ (!Serial.available ()) { ล่าช้า (1); } ch = Serial.read(); if (ch >='0'&& ch <='9') { pinCode = pinCode *10+ (ch -'0'); Serial.print(ch); } } ในขณะที่ ((ch !='\n')); ส่งคืนรหัสพิน; } เป็นโมฆะ onPassKeyNotify (uint32_t pass_key) { ESP_LOGE (LOG_TAG, "หมายเลขแจ้งรหัสผ่าน:%d", pass_key); } bool onConfirmPIN (uint32_t pass_key) { ESP_LOGI (LOG_TAG, "หมายเลขรหัสผ่านใช่/ไม่ใช่:%d", pass_key); vTaskDelay(5000); ผลตอบแทนจริง; } bool onSecurityRequest () { ESP_LOGI (LOG_TAG, "คำขอความปลอดภัย"); กลับมาจริง; } โมฆะ onAuthenticationComplete (esp_ble_auth_cmpl_t auth_cmpl) { Serial.print ("สถานะคู่ = "); Serial.println(auth_cmpl.success); } };

การแจ้งเตือน BLE:

กล้องจะแจ้งไคลเอ็นต์ BLE เกี่ยวกับการเปลี่ยนแปลงของกล้อง รวมถึงเวลาที่กล้องเริ่มและหยุดการบันทึก รหัสนี้สลับ LED ของฉันเมื่อเริ่ม/หยุดการบันทึก

โมฆะคงที่ notifyCallback (BLERemoteCharacteristic * pBLERemoteCharacteristic, uint8_t*pData, size_t length, bool isNotify) {// BMPCC4k BLE message format:// rec on is 255 9 0 0 10 1 1 2 2 0 64 0 2// rec off is 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) { สเตตัส =0; } ถ้า (pData[8] ==2) { สถานะ =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(boolean RecOn) { if (!RecOn) บันทึก [8] =0; บันทึกอื่น[8] =2; pControlCharacteristic->writeValue ((uint8_t*) บันทึก 16 จริง); }

โฟกัส:

กล้องคาดหวังตัวเลข 11 บิตตั้งแต่ระยะใกล้ถึงโฟกัสไกล ฉันแนะนำให้ใส่ตัวกรองบนค่า ADC ของคุณ ไม่เช่นนั้นการโฟกัสอาจทำให้กระวนกระวายใจ

uint8_t โฟกัส = {255, 6, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0}; // 0.0 … 1.0, 11 บิต, [8] = LSB, [9] = MSBvoid Focus (uint16_t val) { // เปลี่ยนจากค่า ADC 12 บิตเป็นโฟกัสค่าโฟกัส 11 บิต [8] = (uint8_t) (((val > >1) &0xFF)); โฟกัส[9] = (uint8_t)(((val >>1) &0xFF00) >>8); pControlCharacteristic->writeValue((uint8_t*)focus, 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) { // เปลี่ยนจากค่า ADC 12 บิตเป็นค่ารูรับแสง 11 บิต [8] = (uint8_t) (((val >> 1) &0xFF)); รูรับแสง[9] = (uint8_t)(((val >>1) &0xFF00) >>8); pControlCharacteristic->writeValue ((uint8_t*) รูรับแสง 12 จริง); }

ขั้นตอนที่ 3: วงจร

The Circuit
The Circuit

ฉันได้แนบ PDF ของวงจรของฉันแล้ว แนบรูปภาพบางส่วนของ PCB มาด้วย

บอร์ดนี้ใช้พลังงานจากไมโคร USB

หลังจากได้รับ PCB ฉันตัดสินใจว่าฉันต้องการขับ RGB LED ดังนั้นฉันจึงเชื่อมต่อ WS2812B สองตัวในซีรีย์เข้ากับเอาต์พุต "Button Led" (ซึ่งจำเป็นต้องมีการต่อลวดบน PCB) PCB อยู่ที่ 8USD กับ OSHPark.com

คุณสามารถดูการเชื่อมต่อเพิ่มเติมบน PCB เช่น "adc" ที่ฉันไม่ได้ใช้และถูกลบออกจากแผนผังที่แนบมา แผนคือการใช้วงล้อโฟกัสภายนอกในอดีต แต่ปัจจุบันฉันพอใจกับวงล้อขนาดเล็กมาก

ขั้นตอนที่ 4: บทสรุป

ฉันหวังว่านี่จะช่วยได้

ฉันมีข้อมูลอัปเดตในอนาคตอยู่แล้ว เช่น การใช้เครื่องเข้ารหัสแบบโรตารี่โดยไม่มีการหยุดแบบฮาร์ดสต็อป สิ่งนี้จะต้องให้คอนโทรลเลอร์ได้รับค่าปัจจุบันของโฟกัสหรือรูรับแสงจากกล้องและดำเนินการต่อจากที่นั่น จำเป็นต้องอัปเดตฟังก์ชัน "notifyCallback" สำหรับสิ่งนั้น

PCB ต้องการการอัปเดตเพื่อให้สัญญาณสำหรับไฟ LED WS2812B RGB อย่างถูกต้อง

ฉันใช้เวลามาก (มาก) ในการทำงานนี้โดยเฉพาะส่วน BLE หากสิ่งนี้ช่วยคุณได้และคุณต้องการซื้อเครื่องดื่มให้ฉัน นั่นถือเป็นการขอบคุณมาก:) นี่คือลิงก์การบริจาคของ Paypal:

แนะนำ: