Table des matières:

Magic Button 4k : la télécommande sans fil 20USD BMPCC 4k (ou 6k) : 4 étapes (avec photos)
Magic Button 4k : la télécommande sans fil 20USD BMPCC 4k (ou 6k) : 4 étapes (avec photos)

Vidéo: Magic Button 4k : la télécommande sans fil 20USD BMPCC 4k (ou 6k) : 4 étapes (avec photos)

Vidéo: Magic Button 4k : la télécommande sans fil 20USD BMPCC 4k (ou 6k) : 4 étapes (avec photos)
Vidéo: ATEM Mini Tips Marathon — All 16 Tips in One Video! 2024, Juillet
Anonim
Image
Image

De nombreuses personnes m'ont demandé de partager quelques détails sur ma manette sans fil pour le BMPCC4k. La plupart des questions portaient sur le contrôle Bluetooth, je vais donc mentionner quelques détails à ce sujet. Je suppose que vous connaissez l'environnement ESP32 Arduino.

Cette version de la télécommande peut contrôler l'enregistrement, la mise au point et l'ouverture de la caméra via Bluetooth. Regardez la vidéo. Il est assez facile d'ajouter plus de fonctions de contrôle conformément au manuel de contrôle Bluetooth du BMPCC4k. Fondamentalement, tout ce qui se trouve dans l'appareil photo peut être contrôlé, d'après ce que j'ai vu.

Ce serait une étape facile d'ajouter un module LIDAR pour mesurer la distance d'un sujet, afin que vous puissiez obtenir une sorte de système de mise au point automatique… Bien qu'il soit douteux que vous puissiez obtenir une mise au point suffisamment précise sur des zones spécifiques telles que les yeux, etc.

MISE À JOUR 2020: j'ai fait la version 3.0. Il est basé sur une roue à rotation libre utilisant un encodeur magnétique. Il se connecte également à mon moteur de mise au point de suivi, qui devient essentiellement un deuxième périphérique Bluetooth (l'ESP32 prend en charge plusieurs connexions Bluetooth). La nouvelle vidéo le démontre.

Si vous souhaitez commander la version 3, veuillez consulter le site Web de MagicButton

Fournitures

Tout module ESP32 avec wifi et bluetooth. J'ai utilisé le TTGO micro32 car il est petit:https://www.banggood.com/LILYGO-TTGO-Micro-32-V2_0…

Une molette de mise au point, n'importe quel potentiomètre ferait l'affaire. J'ai utilisé ce qui suit car il est minuscule: https://www.aliexpress.com/item/32963061806.html?s… Ce type a des arrêts durs aux limites supérieure et inférieure. Dans une future version, j'utiliserai un encodeur rotatif. De cette façon, la mise au point ou l'ouverture ne "saute" pas au réglage actuel de la molette lorsque j'entre dans un mode.

Un bouton d'enregistrement/mode. J'ai utilisé ce qui suit:

Autres composants standards tels que résistances, capuchons, … (voir schéma)

Étape 1: le code

J'utilise la capacité wifi de l'ESP32 soit pour me connecter à un réseau connu en mode AP, soit, lorsque je suis sur le terrain, cela devient une station (STA) à laquelle je peux me connecter. De cette façon, je peux configurer le module. Je n'entrerai pas dans les détails de la section wifi/page Web, je pourrais l'ajouter à un stade ultérieur.

L'ESP32 se connecte à la caméra et devient un client Bluetooth LE. Le code Bluetooth inclus dans le framework ESP32 d'Arduino ne fonctionne pas avec le BMPCC4k. Wakwak-koba l'a réparé pour nous. Merci Wakwak-koba ! J'ai utilisé la bibliothèque BLE d'ici:

github.com/wakwak-koba/arduino-esp32

Néanmoins, cette version de la lib BLE est toujours en cours de développement et la dernière version de BLEUUID.cpp ne semble pas fonctionner pour le moment, alors prenez la version précédente "vérifiée" de ce fichier.

Pour le reste, la plupart de mon code bluetooth est beaucoup selon les exemples BLE inclus dans le framework Arduino:

Certains UUID et variables BLE définissent:

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

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

Le balayage et la boucle principale:

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks{

void onResult(BLEAdvertisedDevice AdvertisedDevice) { Serial.print("BLE Advertised Device found: "); Serial.println(advertisedDevice.toString().c_str()); if (advertisedDevice.haveServiceUUID() && advertisingDevice.getServiceUUID().equals(BlackMagic)) { Serial.print("Trouvé notre appareil !"); AdvertedDevice.getScan()->stop(); myDevice = new BLEAdvertisedDevice(advertisedDevice); doConnect = vrai; } } }; static void scanCompleteCB(BLEScanResults scanResults) { Serial.println("numérisation terminée"); balayage = faux; } void loop(void) { if (!connected && ((uint32_t)(millis() - Timer) > BLE_RESCAN_TIME || (!scanning))) { Serial.println("scanning…"); balayage = vrai; pBLEScan->start(BLE_SCAN_TIME, scanCompleteCB); Minuteur = millis(); } if (doConnect ==true) { if (connectToServer()) { Serial.println("Nous sommes maintenant connectés au serveur BLE."); connecté = vrai; } else { Serial.println("Nous n'avons pas réussi à nous connecter au serveur, nous ne ferons rien de plus."); } doConnect =false; } }

Connexion à la caméra:

bool connectToServer(){

Serial.print("Etablir une connexion avec "); Serial.println(myDevice->getAddress().toString().c_str()); BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT); BLEDevice::setSecurityCallbacks(new 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(new MyClientCallback()); pClient->connect(myDevice); Serial.println(" - Connecté au serveur"); BLEDevice::setMTU(BLEDevice::getMTU()); // OBTENIR LE MODÈLE DE CAMÉRA BLERemoteService *pRemoteService = pClient->getService(DevInfoServiceControlUUID); if (pRemoteService == nullptr) { Serial.print(" - Échec de l'obtention du service d'informations sur le périphérique"); Serial.println(DevInfoServiceControlUUID.toString().c_str()); aller à l'échec; } Serial.println(" - Lecture des informations sur l'appareil"); // Obtention d'une référence à la caractéristique dans le service du serveur BLE distant. BLERemoteCharacteristic *pRemoteCamModelCharacteristic = pRemoteService->getCharacteristic(CamModelcharUUID); if (pRemoteCamModelCharacteristic == nullptr) { Serial.print(" - Impossible de trouver le modèle de caméra"); Serial.println(CamModelcharUUID.toString().c_str()); aller à l'échec; } // Lecture de la valeur de la caractéristique. std::string value = pRemoteCamModelCharacteristic->readValue(); Serial.print("La caméra est "); Serial.println(value.c_str()); if (CamModel != value.c_str()) { Serial.print(" - La caméra n'est pas BMPCC4k"); aller à l'échec; } // OBTENIR LE CONTRLE pRemoteService = pClient->getService(ControlserviceUUID); if (pRemoteService == nullptr) { Serial.print(" - Impossible d'obtenir le service de l'appareil photo"); Serial.println(ControlserviceUUID.toString().c_str()); aller à l'échec; } BLERemoteCharacteristic *pRemoteClientNameCharacteristic = pRemoteService->getCharacteristic(ClientNamecharUUID); if (pRemoteClientNameCharacteristic != nullptr) { pRemoteClientNameCharacteristic->writeValue(MyName.c_str(), MyName.length()); } pControlCharacteristic = pRemoteService->getCharacteristic(ControlcharUUID); if (pControlCharacteristic == nullptr) { Serial.print(" - Impossible d'obtenir la caractéristique de contrôle"); Serial.println(ControlcharUUID.toString().c_str()); aller à l'échec; } pNotifCharacteristic = pRemoteService->getCharacteristic(NotifcharUUID); if (pNotifCharacteristic != nullptr) // && pNotifCharacteristic->canIndicate()) { Serial.println(" - s'abonner à la notification"); const uint8_t indicationOn = {0x2, 0x0}; pNotifCharacteristic->registerForNotify(notifyCallback, false); pNotifCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)indicationOn, 2, true); } renvoie vrai; échec: pClient->déconnecter(); renvoie faux; }

Le rappel connecté/déconnecté:

class MyClientCallback: public BLEClientCallbacks{

void onConnect(BLEClient *pclient) { Serial.println("Nous sommes connectés."); } void onDisconnect(BLEClient *pclient) { connecté =false; pclient->déconnecter(); Serial.println("Nous avons été déconnectés."); } };

La partie code PIN:

Dans ma version actuelle, je peux entrer le code PIN via l'interface Web, mais ce sont des détails sur le wifi/la page Web que je pourrais ajouter plus tard.

classe MySecurity: public BLESecurityCallbacks

{ uint32_t onPassKeyRequest() { Serial.println("- S'IL VOUS PLAÎT ENTRER 6 CHIFFRES PIN (fin avec ENTREE): "); 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')); retourner le code pin; } void onPassKeyNotify(uint32_t pass_key) { ESP_LOGE(LOG_TAG, "Le numéro de notification de la clé d'authentification: %d", pass_key); } bool onConfirmPIN(uint32_t pass_key) { ESP_LOGI(LOG_TAG, "Le mot de passe YES/NO number:%d", pass_key); vTaskDelay(5000); returntrue; } bool onSecurityRequest() { ESP_LOGI(LOG_TAG, "Requête de sécurité"); returntrue; } void onAuthenticationComplete(esp_ble_auth_cmpl_t auth_cmpl) { Serial.print("pair status = "); Serial.println(auth_cmpl.success); } };

Notification BLE:

La caméra informe ses clients BLE de tout changement de caméra, y compris lorsque la caméra démarre et arrête l'enregistrement. Ce code bascule ma LED lorsqu'elle démarre/arrête l'enregistrement.

static void notifyCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t*pData, size_t length, bool isNotify) { // format de message BMPCC4k BLE:// rec on est 255 9 0 0 10 1 1 2 2 0 64 0 2// rec off est 255 9 0 0 10 1 1 2 0 0 64 0 2if (longueur ==13&& pData[0] ==255&& pData[1] ==9&& pData[4] ==10&& pData[5] ==1) { if (pData[8] ==0) { état rec=0; } if (pData[8] ==2) { recstatus =1; } } }

Étape 2: Le Code Partie 2

C'est la partie qui envoie réellement les commandes à la caméra.

Enregistrement:

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

Mise au point:

L'appareil photo attend un nombre de 11 bits, allant de la mise au point proche à lointaine. Je conseille de mettre un filtre sur votre valeur ADC, sinon la mise au point pourrait être nerveuse.

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) { //passer d'une valeur ADC 12bit à une valeur focus 11bit focus[8] = (uint8_t)(((val > >1) &0xFF)); focus[9] = (uint8_t)(((val >>1) &0xFF00) >>8); pControlCharacteristic->writeValue((uint8_t*)focus, 12, true); }

Ouverture:

L'appareil photo attend un nombre de 11 bits, allant d'une valeur d'ouverture faible à élevée. Je conseille de mettre un filtre sur votre valeur ADC, sinon la valeur d'ouverture pourrait être nerveuse.

uint8_t ouverture = {255, 6, 0, 0, 0, 3, 128, 0, 0, 0, 0, 0}; // 0.0 … 1.0, [8]=LSB, [9]=MSBvoid Aperture(uint16_t val) { //passer d'une valeur ADC 12bit à une valeur d'ouverture 11bit ouverture[8] = (uint8_t)(((val >>1) &0xFF)); ouverture[9] = (uint8_t)(((val >>1) &0xFF00) >>8); pControlCharacteristic->writeValue((uint8_t*)ouverture, 12, true); }

Étape 3: Le circuit

Le circuit
Le circuit

J'ai joint le PDF de mon circuit. Quelques photos du PCB sont également jointes.

La carte est alimentée par micro USB.

Après avoir reçu le PCB, j'ai décidé que je voulais piloter une LED RVB, j'ai donc connecté deux WS2812B en série à la sortie "Button Led" (qui nécessitait des patchs de fil sur le PCB). Les PCB coûtaient 8 USD avec OSHPark.com.

Vous pouvez voir d'autres connexions sur le PCB telles que "adc" que je n'utilise pas et qui ont été supprimées des schémas ci-joints. Le plan était d'utiliser une molette de mise au point externe dans le passé, mais je suis actuellement parfaitement satisfait de la petite molette.

Étape 4: Conclusion

J'espère que cela a aidé.

J'ai quelques mises à jour futures en tête, comme l'utilisation d'un encodeur rotatif sans arrêts brusques. Cela nécessitera que le contrôleur obtienne la valeur actuelle de la mise au point ou de l'ouverture de l'appareil photo, et continue à partir de là. La fonction "notifyCallback" doit être mise à jour pour cela probablement.

Le PCB a besoin d'une mise à jour pour fournir correctement les signaux des LED RGB WS2812B.

J'ai passé beaucoup (beaucoup) de temps à faire ce travail, en particulier la partie BLE. Si cela vous a aidé et que vous voulez m'acheter un verre, c'est très apprécié:) Ceci est un lien de don Paypal:

Conseillé: