Spisu treści:

Magiczny przycisk 4k: 20 USD BMPCC 4k (lub 6k) Bezprzewodowy pilot zdalnego sterowania: 4 kroki (ze zdjęciami)
Magiczny przycisk 4k: 20 USD BMPCC 4k (lub 6k) Bezprzewodowy pilot zdalnego sterowania: 4 kroki (ze zdjęciami)

Wideo: Magiczny przycisk 4k: 20 USD BMPCC 4k (lub 6k) Bezprzewodowy pilot zdalnego sterowania: 4 kroki (ze zdjęciami)

Wideo: Magiczny przycisk 4k: 20 USD BMPCC 4k (lub 6k) Bezprzewodowy pilot zdalnego sterowania: 4 kroki (ze zdjęciami)
Wideo: Недорогой капсульный отель в японском стиле за 20 долларов | Ueno Station Hostel Oriental 2024, Listopad
Anonim
Image
Image

Wiele osób prosiło mnie o udostępnienie szczegółów dotyczących mojego bezprzewodowego kontrolera do BMPCC4k. Większość pytań dotyczyła sterowania bluetooth, więc wspomnę kilka szczegółów na ten temat. Zakładam, że znasz środowisko Arduino ESP32.

Ta wersja pilota może sterować nagrywaniem, ostrością i przysłoną aparatu przez bluetooth. Obejrzyj wideo. Dość łatwo jest dodać więcej funkcji sterujących zgodnie z instrukcją obsługi Bluetooth BMPCC4k. W zasadzie wszystko w aparacie można kontrolować, o ile widziałem.

Łatwym krokiem byłoby dodanie modułu LIDAR do pomiaru odległości obiektu, dzięki czemu można uzyskać jakiś system autofokusa… Chociaż jest wątpliwe, czy można uzyskać wystarczająco dokładne ustawienie ostrości na określonych obszarach, takich jak oczy itp.

AKTUALIZACJA 2020: Zrobiłem wersję 3.0. Opiera się na swobodnie obracającym się kole z enkoderem magnetycznym. Łączy się również z moim silnikiem follow focus, który w zasadzie staje się drugim urządzeniem Bluetooth (ESP32 obsługuje wiele połączeń Bluetooth). Nowy film pokazuje to.

Jeśli chcesz zamówić wersję 3, zajrzyj na stronę MagicButton

Kieszonkowe dzieci

Dowolny moduł ESP32 z wifi i bluetooth. Użyłem TTGO micro32, ponieważ jest mały:

Pokrętło ostrości, wystarczy każdy potencjometr. Użyłem następującego, ponieważ jest mały: https://www.aliexpress.com/item/32963061806.html?s…Ten rodzaj ma twarde przystanki na górnej i dolnej granicy. W przyszłej wersji użyję enkodera obrotowego. W ten sposób ostrość lub przysłona nie „przeskakują” do bieżącego ustawienia koła, gdy wchodzę w tryb.

Przycisk nagrywania/trybu. Użyłem następujących:

Inne standardowe komponenty, takie jak rezystory, nakładki, … (patrz schemat)

Krok 1: Kodeks

Korzystam z możliwości Wi-Fi ESP32, aby albo połączyć się ze znaną siecią w trybie AP, albo, gdy jestem w terenie, staje się stacją (STA), z którą mogę się połączyć. W ten sposób mogę skonfigurować moduł. Nie będę wchodził w szczegóły sekcji Wi-Fi/strony internetowej, może dodam to na późniejszym etapie.

ESP32 łączy się z kamerą i staje się klientem Bluetooth LE. Kod bluetooth zawarty w strukturze ESP32 Arduino nie działa z BMPCC4k. Wakwak-koba naprawił to za nas. Dziękuję Wakwak-koba! Korzystałem z biblioteki BLE stąd:

github.com/wakwak-koba/arduino-esp32

Niemniej jednak ta wersja BLE lib jest wciąż w fazie rozwoju, a najnowsza wersja BLEUUID.cpp nie działa w tej chwili, więc weź wcześniejszą "zweryfikowaną" wersję tego pliku.

Co do reszty, większość mojego kodu bluetooth to dużo, jak na przykładach BLE zawartych w frameworku Arduino:

Niektóre BLE UUID i zmienne określają:

statyczny BLEUUID BlackMagic("00001800-0000-1000-8000-00805f9b34fb");

statyczna usługa kontroli BLEUUIDUUID("291D567A-6D75-11E6-8B77-86F30CA893D3"); statyczny BLEUUID DevInfoServiceControlUUID("180A"); statyczny znak kontrolny BLEUUIDUUID("5DD3465F-1AEE-4299-8493-D2ECA2F8E1BB"); statyczny BLEUUID NotifcharUUID("B864E140-76A0-416A-BF30-5876504537D9"); statyczny BLEUUID NazwaKlientacharUUID("FFAC0C52-C9FB-41A0-B063-CC76282EB89C"); statyczny BLEUUID CamModelcharUUID("2A24"); statyczny BLEScan *pBLEScan = BLEDevice::getScan(); statyczny BLAddress *pServerAddress; statyczny BLEAdvertisedDevice* mojeUrządzenie; statyczny BLERemoteCharacteristic *pControlCharacteristic; statyczny BLERemoteCharacteristic *pNotifCharacteristic; statyczne logiczne doConnect =0; połączenie statyczne logiczne =0; skanowanie volatilebool =0; volatileuint32_t kod PIN;

Skanowanie i główna pętla:

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks{

void onResult(BLEAdvertisedDevice anonsowaneDevice) { Serial.print("Znaleziono urządzenie ogłoszone BLE: "); Serial.println(reklamowaneUrządzenie.toString().c_str()); if (advertisedDevice.haveServiceUUID() &&AdvertisedDevice.getServiceUUID().equals(BlackMagic)) { Serial.print("Znaleziono nasze urządzenie!"); AdvertisingdDevice.getScan()->stop(); myDevice = new BLEAdvertisedDevice(advertisedDevice); doConnect =prawda; } } }; static void scanCompleteCB(BLEScanResults scanResults) { Serial.println("skanowanie zakończone"); skanowanie =fałsz; } void loop(void) { if (!connected && ((uint32_t)(millis() - Timer) > BLE_RESCAN_TIME || (!scanning))) { Serial.println("skanowanie…"); skanowanie =prawda; pBLEScan->start(BLE_SCAN_TIME, scanCompleteCB); Zegar = mili(); } if (doConnect ==true) { if (connectToServer()) { Serial.println("Teraz jesteśmy połączeni z serwerem BLE."); połączone =prawda; } else { Serial.println("Nie udało się połączyć z serwerem; nic więcej nie zrobimy."); } doPołącz =fałsz; } }

Podłączanie do kamery:

bool connectToServer(){

Serial.print("Tworzenie połączenia z "); Serial.println(mojeUrządzenie->getAddress().toString().c_str()); BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT); BLEDevice::setSecurityCallbacks(nowy MySecurity()); BLESecurity *pSecurity = nowy 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(nowy MyClientCallback()); pClient->connect(mojeUrządzenie); Serial.println(" - Połączony z serwerem"); BLEDevice::setMTU(BLEDevice::getMTU()); // UZYSKAJ MODEL KAMERY BLERemoteService *pRemoteService = pClient->getService(DevInfoServiceControlUUID); if (pRemoteService == nullptr) { Serial.print(" - Nie udało się uzyskać usługi informacji o urządzeniu"); Serial.println(DevInfoServiceControlUUID.toString().c_str()); iść ponieść porażkę; } Serial.println(" - Odczytywanie informacji o urządzeniu"); // Uzyskaj odniesienie do charakterystyki w usłudze zdalnego serwera BLE. BLERemoteCharacteristic *pRemoteCamModelCharacteristic = pRemoteService->getCharacteristic(CamModelcharUUID); if (pRemoteCamModelCharacteristic == nullptr) { Serial.print(" - Nie udało się znaleźć modelu kamery"); Serial.println(CamModelcharUUID.toString().c_str()); iść do porażki; } // Odczytaj wartość charakterystyki. std::string value = pRemoteCamModelCharacteristic->readValue(); Serial.print("Kamera jest"); Serial.println(wartość.c_str()); if (CamModel != value.c_str()) { Serial.print(" - Kamera nie jest BMPCC4k"); iść do porażki; } // UZYSKAJ KONTROLĘ pRemoteService = pClient->getService(ControlserviceUUID); if (pRemoteService == nullptr) { Serial.print(" - Nie udało się uzyskać usługi kamery"); Serial.println(ControlserviceUUID.toString().c_str()); iść ponieść porażkę; } BLERemoteCharacteristic *pRemoteClientNameCharacteristic = pRemoteService->getCharacteristic(NazwaKlientacharUUID); if (pCharakterystykaNazwaKlientaZdalnego != nullptr) { pCharakterystykaNazwaKlientaZdalnego->writeValue(MojaNazwa.c_str(), MojaNazwa.length()); } pControlCharacteristic = pRemoteService->getCharacteristic(ControlcharUUID); if (pControlCharacteristic == nullptr) { Serial.print("- Nie udało się uzyskać charakterystyki kontrolnej"); Serial.println(CharakterUUID.toString().c_str()); iść do porażki; } pNotifCharacteristic = pRemoteService->getCharacteristic(NotifcharUUID); if (pNotifCharacteristic != nullptr) // && pNotifCharacteristic->canIndicate()) { Serial.println(" - subskrybowanie powiadomień"); const uint8_t wskazanieOn = {0x2, 0x0}; pNotifCharacteristic->registerForNotify(notifyCallback, false); pNotifCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)indicationOn, 2, true); } zwróć prawdę; błąd: pClient->disconnect(); zwróć fałsz; }

Połączony/rozłączony wywołanie zwrotne:

class MyClientCallback: publiczne BLEClientCallbacks{

void onConnect(BLEClient *pclient) { Serial.println("Jesteśmy połączeni."); } void onDisconnect(BLEClient *pclient) { podłączony =false; klient->rozłącz(); Serial.println("Zostaliśmy rozłączeni."); } };

Część kodu PIN:

W mojej obecnej wersji mogę wprowadzić kod PIN przez interfejs sieciowy, ale są to szczegóły dotyczące Wi-Fi/strony internetowej, które mogę dodać później.

class MySecurity: publiczne BLESecurityCallbacks

{ uint32_t onPassKeyRequest() { Serial.println("- PROSZĘ WPROWADZIĆ 6-CYFROWY PIN (zakończ na ENTER): "); kod PIN =0; char ch; zrobić { while (! Serial.available ()) { opóźnienie (1); } ch = Serial.odczyt(); if (ch >='0'&& ch <='9') { pinCode = pinCode *10+ (ch -'0'); Serial.print(ch); } } while ((ch !='\n')); zwróć kod PIN; } void onPassKeyNotify(uint32_t pass_key) { ESP_LOGE(LOG_TAG, "Passkey Notify number:%d", pass_key); } bool onConfirmPIN(uint32_t pass_key) { ESP_LOGI(LOG_TAG, "hasło TAK/NIE numer:%d", pass_key); vTaskDelay(5000); powrótprawda; } bool onSecurityRequest() { ESP_LOGI(LOG_TAG, "Żądanie bezpieczeństwa"); powrótprawda; } void onAuthenticationComplete(esp_ble_auth_cmpl_t auth_cmpl) { Serial.print("status pary = "); Serial.println(auth_cmpl.success); } };

Powiadomienie BLE:

Kamera powiadamia klientów BLE o wszelkich zmianach kamery, w tym o rozpoczęciu i zakończeniu nagrywania przez kamerę. Ten kod przełącza moją diodę LED, gdy rozpoczyna/zatrzymuje nagrywanie.

static void notificationCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t*pData, size_t length, bool isNotify) { // format komunikatu BMPCC4k BLE:// rec on to 255 9 0 0 10 1 1 2 2 0 64 0 2// rec off to 255 9 0 0 10 1 1 2 0 0 64 0 2if (długość ==13&& pData[0] ==255&& pData[1] ==9&& pData[4] ==10&& pData[5] ==1) { if (pData[8] ==0) { stan odwrócony =0; } if (pData[8] ==2) { recstatus =1; } } }

Krok 2: Kod, część 2

Jest to część, która faktycznie wysyła polecenia do kamery.

Nagranie:

uint8_t rekord = {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) record[8] =0; w przeciwnym razie zapis[8] =2; pControlCharacteristic->writeValue((uint8_t*)record, 16, true); }

Skupienie:

Aparat oczekuje 11-bitowej liczby, od bliskiej do dalekiej ostrości. Radzę umieścić filtr na wartości ADC, w przeciwnym razie ostrość może nerwowo drgać.

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) { //przejście z 12-bitowej wartości ADC do 11-bitowej wartości ostrości [8] = (uint8_t)(((val > >1) &0xFF)); focus[9] = (uint8_t)(((val >>1) &0xFF00) >>8); pControlCharacteristic->writeValue((uint8_t*)focus, 12, true); }

Otwór:

Aparat oczekuje 11-bitowej liczby, od niskiej do wysokiej wartości przysłony. Radzę umieścić filtr na wartości ADC, w przeciwnym razie wartość przysłony może nerwowo drgać.

uint8_t apertura = {255, 6, 0, 0, 0, 3, 128, 0, 0, 0, 0, 0}; // 0.0 … 1.0, [8]=LSB, [9]=MSBvoid Aperture(uint16_t val) { //przejście od 12-bitowej wartości ADC do 11-bitowej apertury wartości apertury[8] = (uint8_t)(((val >>1) &0xFF)); przysłona[9] = (uint8_t)(((val >>1) &0xFF00) >>8); pControlCharacteristic->writeValue((uint8_t*)przysłona, 12, prawda); }

Krok 3: Obwód

Obwód
Obwód

Załączam plik PDF mojego obwodu. Załączam również kilka zdjęć PCB.

Płytka zasilana jest przez micro USB.

Po otrzymaniu płytki zdecydowałem, że chcę sterować diodą LED RGB, więc podłączyłem szeregowo dwa WS2812B do wyjścia „Button Led” (które wymagało łatania przewodów na płytce drukowanej). PCB kosztowało 8 USD z OHPpark.com.

Na płytce widać więcej połączeń typu „adc”, których nie używam i które zostały usunięte z załączonych schematów. W przeszłości planowałem używać zewnętrznego pokrętła ostrości, ale obecnie jestem całkowicie zadowolony z małego pokrętła.

Krok 4: Wniosek

Mam nadzieję, że to pomogło.

Mam na myśli kilka przyszłych aktualizacji, takich jak użycie enkodera obrotowego bez twardych ograniczników. Będzie to wymagało od kontrolera pobrania bieżącej wartości ostrości lub przysłony z aparatu i kontynuowania od tego momentu. Prawdopodobnie w tym celu należy zaktualizować funkcję „notifyCallback”.

PCB wymaga aktualizacji, aby prawidłowo dostarczać sygnały do diod LED RGB WS2812B.

Spędziłem dużo (dużo) czasu na tworzeniu tej pracy, zwłaszcza części BLE. Jeśli ci to pomogło i chcesz kupić mi drinka, to bardzo doceniam:) To jest link do darowizny Paypal:

Zalecana: