Inhaltsverzeichnis:

Magic Button 4k: die 20USD BMPCC 4k (oder 6k) drahtlose Fernbedienung - Gunook
Magic Button 4k: die 20USD BMPCC 4k (oder 6k) drahtlose Fernbedienung - Gunook

Video: Magic Button 4k: die 20USD BMPCC 4k (oder 6k) drahtlose Fernbedienung - Gunook

Video: Magic Button 4k: die 20USD BMPCC 4k (oder 6k) drahtlose Fernbedienung - Gunook
Video: ATEM Mini Tips Marathon — All 16 Tips in One Video! 2024, Juli
Anonim
Image
Image

Viele Leute haben mich gebeten, einige Details zu meinem drahtlosen Controller für den BMPCC4k mitzuteilen. Die meisten Fragen betrafen die Bluetooth-Steuerung, daher werde ich ein paar Details dazu erwähnen. Ich gehe davon aus, dass Sie mit der ESP32-Arduino-Umgebung vertraut sind.

Diese Version der Fernbedienung kann die Aufnahme, den Fokus und die Blende der Kamera über Bluetooth steuern. Schauen Sie sich das Video an. Es ist ganz einfach, weitere Steuerungsfunktionen gemäß dem Bluetooth-Steuerungshandbuch des BMPCC4k hinzuzufügen. Grundsätzlich kann alles in der Kamera gesteuert werden, soweit ich das gesehen habe.

Es wäre ein einfacher Schritt, ein LIDAR-Modul hinzuzufügen, um die Entfernung eines Objekts zu messen, so dass Sie eine Art Autofokussystem erhalten können … Obwohl es fraglich ist, ob Sie einen ausreichend genauen Fokus auf bestimmte Bereiche wie Augen usw. erzielen können …

UPDATE 2020: Ich habe Version 3.0 erstellt. Es basiert auf einem frei rotierenden Rad mit einem magnetischen Encoder. Es verbindet sich auch mit meinem Follow Focus Motor, der im Grunde ein zweites Bluetooth-Gerät wird (der ESP32 unterstützt mehrere Bluetooth-Verbindungen). Das zeigt das neue Video.

Wenn Sie Version 3 bestellen möchten, schauen Sie bitte auf die MagicButton-Website

Lieferungen

Jedes ESP32-Modul mit WLAN und Bluetooth. Ich habe das TTGO micro32 verwendet, weil es winzig ist:

Ein Fokusrad, jedes Potentiometer würde reichen. Ich habe Folgendes verwendet, weil es winzig ist: https://www.aliexpress.com/item/32963061806.html?s…Diese Art hat harte Stopps an der oberen und unteren Grenze. In einer zukünftigen Version werde ich einen Drehgeber verwenden. Auf diese Weise "springt" der Fokus oder die Blende nicht auf die aktuelle Radeinstellung, wenn ich in einen Modus gehe.

Eine Aufnahme-/Modustaste. Ich habe folgendes verwendet:

Weitere Standardkomponenten wie Widerstände, Kappen, … (siehe Schema)

Schritt 1: Der Code

Ich nutze die WLAN-Fähigkeit des ESP32, um mich entweder im AP-Modus mit einem bekannten Netzwerk zu verbinden, oder wenn ich im Feld bin, wird es zu einer Station (STA), mit der ich eine Verbindung herstellen kann. So kann ich das Modul konfigurieren. Ich werde nicht auf den Abschnitt WLAN/Webseite eingehen, ich könnte dies zu einem späteren Zeitpunkt hinzufügen.

Der ESP32 verbindet sich mit der Kamera und wird zum Bluetooth LE-Client. Der im ESP32-Framework von Arduino enthaltene Bluetooth-Code funktioniert nicht mit dem BMPCC4k. Wakwak-koba hat es für uns repariert. Danke Wakwak-koba! Ich habe die BLE-Bibliothek von hier aus verwendet:

github.com/wakwak-koba/arduino-esp32

Trotzdem befindet sich diese Version der BLE-Bibliothek noch in der Entwicklung und die neueste Version von BLEUUID.cpp scheint im Moment nicht zu funktionieren, also nehmen Sie die frühere "verifizierte" Version dieser Datei.

Im Übrigen entspricht der Großteil meines Bluetooth-Codes den im Arduino-Framework enthaltenen BLE-Beispielen:

Einige BLE-UUIDs und -Variablen definieren:

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

statische BLEUUID ControlserviceUUID("291D567A-6D75-11E6-8B77-86F30CA893D3"); statische BLEUUID DevInfoServiceControlUUID("180A"); statische BLEUUID ControlcharUUID("5DD3465F-1AEE-4299-8493-D2ECA2F8E1BB"); statische BLEUUID NotifcharUUID("B864E140-76A0-416A-BF30-5876504537D9"); statische BLEUUID ClientNamecharUUID("FFAC0C52-C9FB-41A0-B063-CC76282EB89C"); statische BLEUUID CamModelcharUUID("2A24"); statisches BLEScan *pBLEScan = BLEDevice::getScan(); statische BLEAddress *pServerAddress; statisches BLEAdvertisedDevice* myDevice; statisches BLERemoteCharacteristic *pControlCharacteristic; statisch BLERemoteCharacteristic *pNotifCharacteristic; statisch boolesch doConnect =0; statisch boolesch verbunden =0; volatilebool-Abtastung = 0; volatileuint32_t PinCode;

Das Scannen und die Hauptschleife:

Klasse MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks{

Void onResult (BLEAdvertisedDevice advertisedDevice) {Serial.print ("BLE Advertised Device found:"); Serial.println (advertisedDevice.toString().c_str()); if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(BlackMagic)) {Serial.print("Unser Gerät gefunden!"); AdvertisedDevice.getScan()->stop(); myDevice = new BLEAdvertisedDevice(advertisedDevice); doConnect =true; } } }; statisches Void scanCompleteCB (BLEScanResults scanResults) { Serial.println ("Scannen durchgeführt"); Scannen = falsch; aufrechtzuerhalten. Void Schleife (void) { if (!connected && ((uint32_t)(millis() - Timer)> BLE_RESCAN_TIME || (!scanning))) {Serial.println("scanning…"); Scannen = wahr; pBLEScan->start(BLE_SCAN_TIME, scanCompleteCB); Timer = Millis(); } if (doConnect ==true) { if (connectToServer ()) { Serial.println ("Wir sind jetzt mit dem BLE-Server verbunden."); verbunden = wahr; } else { Serial.println("Wir konnten keine Verbindung zum Server herstellen; es gibt nichts mehr, was wir tun werden."); } doConnect =false; } }

Anschließen an die Kamera:

bool connectToServer(){

Serial.print ("Herstellen einer Verbindung zu"); Serial.println (myDevice->getAddress().toString().c_str()); BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT); BLEDevice::setSecurityCallbacks(neue MySecurity()); BLESecurity *pSecurity = new 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(neuer MyClientCallback()); pClient->connect(myDevice); Serial.println(" - Mit dem Server verbunden"); BLEDevice::setMTU(BLEDevice::getMTU()); // KAMERAMODELL BLERemoteService abrufen *pRemoteService = pClient->getService(DevInfoServiceControlUUID); if (pRemoteService == nullptr) { Serial.print (" - Fehler beim Abrufen des Geräteinfo-Dienstes"); Serial.println (DevInfoServiceControlUUID.toString().c_str()); ich muss scheitern; } Serial.println (" - Geräteinformationen lesen"); // Eine Referenz auf das Merkmal im Dienst des entfernten BLE-Servers abrufen. BLERemoteCharacteristic *pRemoteCamModelCharacteristic = pRemoteService->getCharacteristic(CamModelcharUUID); if (pRemoteCamModelCharacteristic == nullptr) {Serial.print (" - Kameramodell konnte nicht gefunden werden"); Serial.println (CamModelcharUUID.toString().c_str()); ich muss scheitern; } // Lesen Sie den Wert des Merkmals. std::string value = pRemoteCamModelCharacteristic->readValue(); Serial.print ("Kamera ist"); Serial.println (value.c_str()); if (CamModel!= value.c_str()) {Serial.print(" - Kamera ist nicht BMPCC4k"); ich muss scheitern; } // STEUERUNG ERHALTEN pRemoteService = pClient->getService(ControlserviceUUID); if (pRemoteService == nullptr) { Serial.print (" - Kameradienst konnte nicht abgerufen werden"); Serial.println (ControlserviceUUID.toString().c_str()); ich muss scheitern; } BLERemoteCharacteristic *pRemoteClientNameCharacteristic = pRemoteService->getCharacteristic(ClientNamecharUUID); if (pRemoteClientNameCharacteristic != nullptr) { pRemoteClientNameCharacteristic->writeValue(MyName.c_str(), MyName.length()); } pControlCharacteristic = pRemoteService->getCharacteristic(ControlcharUUID); if (pControlCharacteristic == nullptr) {Serial.print (" - Steuercharakteristik konnte nicht abgerufen werden"); Serial.println (ControlcharUUID.toString().c_str()); ich muss scheitern; } pNotifCharacteristic = pRemoteService->getCharacteristic(NotifcharUUID); if (pNotifCharacteristic != nullptr) // && pNotifCharacteristic->canIndicate()) { Serial.println(" - Benachrichtigung abonnieren"); const uint8_t AnzeigeOn = {0x2, 0x0}; pNotifCharacteristic->registerForNotify(notifyCallback, false); pNotifCharacteristic->getDescriptor(BLEUUID(((uint16_t)0x2902))->writeValue((uint8_t*)indicationOn, 2, true); } true zurückgeben; fehlschlagen: pClient->disconnect(); falsch zurückgeben; }

Der verbundene/getrennte Rückruf:

Klasse MyClientCallback: public BLEClientCallbacks{

Void onConnect (BLEClient * pclient) { Serial.println ("Wir sind verbunden."); aufrechtzuerhalten. Void onDisconnect (BLEClient * pclient) { verbunden = false; pclient->disconnect(); Serial.println ("Wir haben die Verbindung getrennt."); } };

Der Pincode-Teil:

In meiner aktuellen Version kann ich den PIN-Code über das Webinterface eingeben, aber dies sind WLAN- / Webseitendetails, die ich später hinzufügen könnte.

Klasse MySecurity: öffentliche BLESecurityCallbacks

{ uint32_t onPassKeyRequest () { Serial.println ("- BITTE 6-STELLIGE PIN EINGEBEN (mit ENTER enden): "); 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 zurückgeben; } void onPassKeyNotify(uint32_t pass_key) { ESP_LOGE(LOG_TAG, "Die Passkey-Notify-Nummer:%d", pass_key); } bool onConfirmPIN(uint32_t pass_key) { ESP_LOGI(LOG_TAG, "Der Passkey YES/NO number:%d", pass_key); vTaskDelay(5000); Rückgabewahr; } bool onSecurityRequest() { ESP_LOGI(LOG_TAG, "Sicherheitsanfrage"); Rückgabewahr; aufrechtzuerhalten. Void onAuthenticationComplete (esp_ble_auth_cmpl_t auth_cmpl) { Serial.print ("pair status = "); Serial.println (auth_cmpl.success); } };

BLE-Benachrichtigung:

Die Kamera benachrichtigt ihre BLE-Clients über alle Kameraänderungen, einschließlich wenn die Kamera die Aufnahme startet und stoppt. Dieser Code schaltet meine LED um, wenn sie die Aufnahme startet / stoppt.

static void notificationCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t*pData, size_t length, bool isNotify) { // BMPCC4k BLE Nachrichtenformat:// rec on ist 255 9 0 0 10 1 1 2 2 0 64 0 2// rec off ist 255 9 0 0 10 1 1 2 0 0 64 0 2if (Länge ==13&& pData[0] ==255&& pData[1] ==9&& pData[4] ==10&& pData[5] ==1) { if (pData[8] ==0) { Wiederholungsstatus = 0; aufrechtzuerhalten. Wenn (pData[8] ==2) { recstatus = 1; } } }

Schritt 2: Der Code Teil 2

Dies ist der Teil, der die Befehle tatsächlich an die Kamera sendet.

Aufzeichnung:

uint8_t record = {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; Sonst Datensatz[8] =2; pControlCharacteristic->writeValue((uint8_t*)record, 16, true); }

Fokussierung:

Die Kamera erwartet eine 11-Bit-Zahl, die von nah bis fern reicht. Ich empfehle, einen Filter auf Ihren ADC-Wert zu setzen, da sonst der Fokus nervös zittern kann.

uint8_t Fokus = {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) { //von einem 12bit ADC Wert auf einen 11bit Fokuswert Focus[8] = (uint8_t)(((val > >1) &0xFF)); focus[9] = (uint8_t)(((val >>1) &0xFF00) >>8); pControlCharacteristic->writeValue((uint8_t*)focus, 12, true); }

Öffnung:

Die Kamera erwartet eine 11-Bit-Zahl, die von einem niedrigen bis zu einem hohen Blendenwert reicht. Ich empfehle, einen Filter auf Ihren ADC-Wert zu setzen, da sonst der Blendenwert nervös zittern kann.

uint8_t Blende = {255, 6, 0, 0, 0, 3, 128, 0, 0, 0, 0, 0}; // 0.0 … 1.0, [8]=LSB, [9]=MSBvoid Aperture(uint16_t val) { //von einem 12-Bit-ADC-Wert auf einen 11-Bit-Aperturwert wechseln Apertur[8] = (uint8_t)(((val >>1) &0xFF)); Blende[9] = (uint8_t)(((val >>1) &0xFF00) >>8); pControlCharacteristic->writeValue((uint8_t*)aperture, 12, true); }

Schritt 3: Die Schaltung

Die Rennbahn
Die Rennbahn

Ich habe das PDF meiner Schaltung angehängt. Einige Bilder der Platine sind auch beigefügt.

Das Board wird über Micro-USB mit Strom versorgt.

Nachdem ich die Platine erhalten hatte, entschied ich, dass ich eine RGB-LED ansteuern wollte, also schloss ich zwei WS2812B in Reihe an den "Button Led" -Ausgang an (dafür waren einige Drahtpatches auf der Platine erforderlich). Die PCBs waren 8 USD bei OSHPark.com.

Sie können einige weitere Verbindungen auf der Platine sehen, z. B. "adc", die ich nicht verwende und die aus den beigefügten Schaltplänen entfernt wurden. Früher war geplant, ein externes Fokussierrad zu verwenden, aber mit dem kleinen Daumenrad bin ich derzeit vollkommen zufrieden.

Schritt 4: Fazit

Ich hoffe, das hat geholfen.

Ich habe einige zukünftige Updates im Kopf, wie zum Beispiel die Verwendung eines Drehgebers ohne Hardstops. Dazu muss der Controller den aktuellen Wert des Fokus oder der Blende von der Kamera abrufen und von dort aus fortfahren. Die Funktion "notifyCallback" muss dafür wahrscheinlich aktualisiert werden.

Die Platine benötigt ein Update, um die Signale für die WS2812B RGB-LEDs korrekt bereitzustellen.

Ich habe viel (viel) Zeit damit verbracht, diese Arbeit zu machen, insbesondere den BLE-Teil. Wenn dir das geholfen hat und du mir einen Drink kaufen möchtest, ist das sehr willkommen:) Dies ist ein Paypal-Spendenlink:

Empfohlen: