Taula de continguts:

Magic Button 4k: el control remot sense fils de 20USD BMPCC 4k (o 6k): 4 passos (amb imatges)
Magic Button 4k: el control remot sense fils de 20USD BMPCC 4k (o 6k): 4 passos (amb imatges)

Vídeo: Magic Button 4k: el control remot sense fils de 20USD BMPCC 4k (o 6k): 4 passos (amb imatges)

Vídeo: Magic Button 4k: el control remot sense fils de 20USD BMPCC 4k (o 6k): 4 passos (amb imatges)
Vídeo: ATEM Mini Tips Marathon — All 16 Tips in One Video! 2024, Desembre
Anonim
Image
Image

Molta gent m’ha demanat que compartís alguns detalls sobre el meu controlador sense fils per al BMPCC4k. La majoria de preguntes eren sobre el control del bluetooth, de manera que en mencionaré alguns detalls. Suposo que coneixeu l’entorn ESP32 Arduino.

Aquesta versió del comandament a distància permet controlar la gravació, l'enfocament i l'obertura de la càmera mitjançant bluetooth. Mireu el vídeo. És bastant fàcil afegir més funcions de control segons el manual de control Bluetooth del BMPCC4k. Bàsicament, tot el que es pot controlar a la càmera, pel que he vist.

Seria un pas senzill afegir un mòdul LIDAR per mesurar la distància d’un subjecte, de manera que pugueu obtenir algun tipus de sistema d’enfocament automàtic … Tot i que és qüestionable si podeu obtenir un focus prou precís en àrees específiques com ara ulls, etc.

ACTUALITZACIÓ 2020: he fet la versió 3.0. Es basa en una roda giratòria lliure que utilitza un codificador magnètic. També es connecta al meu motor de focus seguit, que bàsicament es converteix en un segon dispositiu bluetooth (l’ESP32 admet múltiples connexions bluetooth). El nou vídeo ho demostra.

Si voleu demanar la versió 3, consulteu el lloc web MagicButton

Subministraments

Qualsevol mòdul ESP32 amb wifi i bluetooth. He utilitzat el TTGO micro32 perquè és petit:

Una roda d'enfocament, qualsevol potenciòmetre faria. He utilitzat el següent perquè és petit: https://www.aliexpress.com/item/32963061806.html? S … Aquest tipus té parades dures al límit superior i inferior. En una versió futura utilitzaré un codificador rotatiu. D'aquesta manera, el focus o l'obertura no "salta" a la configuració actual de la roda quan entro en un mode.

Un botó rec / mode. He utilitzat el següent: https://www.aliexpress.com/item/32806223591.html? S …

Altres components estàndard com ara resistències, taps, … (veure esquema)

Pas 1: el codi

Utilitzo la capacitat de wifi de l’ESP32 per connectar-me a una xarxa coneguda en mode AP o, quan estic al camp, es converteix en una estació (STA) a la qual em puc connectar. D'aquesta manera puc configurar el mòdul. No entraré en els detalls de la secció de wifi / pàgina web, és possible que ho afegeixi més endavant.

L'ESP32 es connecta a la càmera i es converteix en un client Bluetooth LE. El codi bluetooth inclòs al framework ESP32 d'Arduino no funciona amb el BMPCC4k. Wakwak-koba ens ho ha solucionat. Gràcies Wakwak-koba! He fet servir la biblioteca BLE d’aquí:

github.com/wakwak-koba/arduino-esp32

Tanmateix, aquesta versió de la BLE lib encara està en desenvolupament i l'última versió de BLEUUID.cpp no sembla funcionar en aquest moment, així que preneu la versió "verificada" anterior d'aquest fitxer.

Per la resta, la majoria del meu codi bluetooth és molt gran segons els exemples BLE inclosos al framework Arduino:

Alguns BLE UUID i variables defineixen:

estàtic BLEUUID BlackMagic ("00001800-0000-1000-8000-00805f9b34fb");

static BLEUUID ControlserviceUUID ("291D567A-6D75-11E6-8B77-86F30CA893D3"); estàtic BLEUUID DevInfoServiceControlUUID ("180A"); control estàtic BLEUUIDUUID ("5DD3465F-1AEE-4299-8493-D2ECA2F8E1BB"); estàtic BLEUUID NotifcharUUID ("B864E140-76A0-416A-BF30-5876504537D9"); BLEUUID estàtic ClientNamecharUUID ("FFAC0C52-C9FB-41A0-B063-CC76282EB89C"); estàtic BLEUUID CamModelcharUUID ("2A24"); estàtic BLEScan * pBLEScan = BLEDevice:: getScan (); BLEAddress estàtica * pServerAddress; static BLEAdvertisedDevice * myDevice; BLERemoteCharacteristic estàtic * pControlCharacteristic; BLERemoteCharacteristic estàtic * pNotifCharacteristic; booleà estàtic doConnect = 0; booleà estàtic connectat = 0; volatilebool scanning = 0; volatileuint32_t pinCode;

L’escaneig i el bucle principal:

classe MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {

void onResult (BLEAdvertisedDevice advertisedDevice) {Serial.print ("S'ha trobat el dispositiu anunciat BLE:"); Serial.println (advertisedDevice.toString (). C_str ()); if (advertisedDevice.haveServiceUUID () && advertisedDevice.getServiceUUID (). equals (BlackMagic)) {Serial.print ("Hem trobat el nostre dispositiu!"); advertisedDevice.getScan () -> stop (); myDevice = new BLEAdvertisedDevice (advertisedDevice); doConnect = cert; }}}; static void scanCompleteCB (BLEScanResults scanResults) {Serial.println ("escaneig fet"); escaneig = fals; } bucle buit (buit) {if (! connectat && ((uint32_t) (millis () - Temporitzador)> BLE_RESCAN_TIME || (! escaneig))) {Serial.println ("escaneig …"); escaneig = cert; pBLEScan-> start (BLE_SCAN_TIME, scanCompleteCB); Temporitzador = millis (); } if (doConnect == true) {if (connectToServer ()) {Serial.println ("Ara estem connectats al servidor BLE."); connectat = cert; } else {Serial.println ("No hem pogut connectar al servidor; no farem res més."); } doConnect = fals; }}

Connexió a la càmera:

bool connectToServer () {

Serial.print ("Formació d'una connexió a"); Serial.println (myDevice-> getAddress (). ToString (). C_str ()); BLEDevice:: setEncryptionLevel (ESP_BLE_SEC_ENCRYPT); BLEDevice:: setSecurityCallbacks (nova MySecurity ()); BLESecurity * pSecurity = nova BLESecurity (); pSeguretat-> setKeySize (); pSeguretat-> setAuthenticationMode (ESP_LE_AUTH_REQ_SC_MITM_BOND); pSeguretat-> setCapability (ESP_IO_CAP_IN); pSeguretat-> setRespEncryptionKey (ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK); BLEClient * pClient = BLEDevice:: createClient (); pClient-> setClientCallbacks (nou MyClientCallback ()); pClient-> connect (myDevice); Serial.println ("- Connectat al servidor"); BLEDevice:: setMTU (BLEDevice:: getMTU ()); // OBTENCIÓ DEL MODEL DE CÀMERA BLERemoteService * pRemoteService = pClient-> getService (DevInfoServiceControlUUID); if (pRemoteService == nullptr) {Serial.print ("- No s'ha pogut obtenir el servei d'informació del dispositiu"); Serial.println (DevInfoServiceControlUUID.toString (). C_str ()); anar fracassat; } Serial.println ("- Lectura d'informació del dispositiu"); // Obteniu una referència a la característica al servei del servidor BLE remot. BLERemoteCharacteristic * pRemoteCamModelCharacteristic = pRemoteService-> getCharacteristic (CamModelcharUUID); if (pRemoteCamModelCharacteristic == nullptr) {Serial.print ("- No s'ha pogut trobar el model de càmera"); Serial.println (CamModelcharUUID.toString (). C_str ()); anar fracassat; } // Llegiu el valor de la característica. std:: string value = pRemoteCamModelCharacteristic-> readValue (); Serial.print ("La càmera és"); Serial.println (value.c_str ()); if (CamModel! = value.c_str ()) {Serial.print ("- La càmera no és BMPCC4k"); anar fracassat; } // OBTENIR CONTROL pRemoteService = pClient-> getService (ControlserviceUUID); if (pRemoteService == nullptr) {Serial.print ("- No s'ha pogut obtenir el servei de càmera"); Serial.println (ControlserviceUUID.toString (). C_str ()); anar fracassat; } BLERemoteCharacteristic * pRemoteClientNameCharacteristic = pRemoteService-> getCharacteristic (ClientNamecharUUID); if (pRemoteClientNameCharacteristic! = nullptr) {pRemoteClientNameCharacteristic-> writeValue (MyName.c_str (), MyName.length ()); } pControlCharacteristic = pRemoteService-> getCharacteristic (ControlcharUUID); if (pControlCharacteristic == nullptr) {Serial.print ("- No s'ha pogut obtenir la característica de control"); Serial.println (ControlcharUUID.toString (). C_str ()); anar fracassat; } pNotifCharacteristic = pRemoteService-> getCharacteristic (NotifcharUUID); if (pNotifCharacteristic! = nullptr) // && pNotifCharacteristic-> canIndicate ()) {Serial.println ("- subscripció a la notificació"); const uint8_t indicationOn = {0x2, 0x0}; pNotifCharacteristic-> registerForNotify (notificationCallback, false); pNotifCharacteristic-> getDescriptor (BLEUUID ((uint16_t) 0x2902)) -> writeValue ((uint8_t *) indicationOn, 2, true); } tornar cert; falla: pClient-> disconnect (); tornar fals; }

La devolució de trucada connectada / desconnectada:

classe MyClientCallback: BLEClientCallbacks públics {

void onConnect (BLEClient * pclient) {Serial.println ("Estem connectats"); } void onDisconnect (BLEClient * pclient) {connectat = fals; pclient-> disconnect (); Serial.println ("Ens hem desconnectat"); }};

La part del codi PIN:

A la meva versió actual puc introduir el codi PIN a través de la interfície web, però es tracta de detalls de pàgina web / wifi que puc afegir més endavant.

classe MySecurity: BLESecurityCallbacks públics

{uint32_t onPassKeyRequest () {Serial.println ("- SI US PLAU ENTRAR 6 DIGIT PIN (finalitzar amb ENTER):"); pinCode = 0; char ch; fer {while (! Serial.available ()) {delay (1); } ch = Serial.read (); if (ch> = '0' && ch <= '9') {pinCode = pinCode * 10 + (ch -'0 '); Serial.print (ch); }} while ((ch! = '\ n')); retorn pinCode; } void onPassKeyNotify (uint32_t pass_key) {ESP_LOGE (LOG_TAG, "El número de notificació de contrasenya:% d", pass_key); } bool onConfirmPIN (uint32_t pass_key) {ESP_LOGI (LOG_TAG, "La contrasenya número SÍ / NO:% d", pass_key); vTaskDelay (5000); returntrue; } bool onSecurityRequest () {ESP_LOGI (LOG_TAG, "Sol·licitud de seguretat"); returntrue; } void onAuthenticationComplete (esp_ble_auth_cmpl_t auth_cmpl) {Serial.print ("pair status ="); Serial.println (auth_cmpl.success); }};

Notificació BLE:

La càmera notifica als seus clients BLE sobre qualsevol canvi de càmera, inclòs quan la càmera s'inicia i deixa de gravar. Aquest codi commuta el meu LED quan comença / atura la gravació.

static void notificationCallback (BLERemoteCharacteristic * pBLERemoteCharacteristic, uint8_t * pData, size_t length, bool isNotify) {// BMPCC4k Format de missatge BLE: // 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 (longitud == 13 && pData [0] == 255 && pData [1] == 9 && pData [4] == 10 && pData [5] == 1) {if (pData [8] == 0) { recstatus = 0; } if (pData [8] == 2) {recstatus = 1; }}}

Pas 2: el codi, part 2

Aquesta és la part que realment envia les ordres a la càmera.

Gravació:

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

Enfocament:

La càmera espera un nombre d’11 bits, que va des del focus proper fins al llunyà. Aconsello posar un filtre al vostre valor ADC, en cas contrari el focus pot ser nerviós.

uint8_t focus = {255, 6, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0}; // 0,0 … 1,0, 11 bits, [8] = LSB, [9] = MSBvoid Focus (uint16_t val) {// passant d'un valor ADC de 12 bits a un focus de valor de focus de 11 bits [8] = (uint8_t) (((val> > 1) & 0xFF)); focus [9] = (uint8_t) (((val >> 1) & 0xFF00) >> 8); pControlCharacteristic-> writeValue ((uint8_t *) focus, 12, true); }

Obertura:

La càmera espera un nombre d’11 bits, que va des d’un valor d’obertura baix fins a un alt. Aconsello posar un filtre al vostre valor ADC, en cas contrari, el valor de l'obertura pot ser nerviós.

uint8_t oberture = {255, 6, 0, 0, 0, 3, 128, 0, 0, 0, 0, 0}; // 0,0 … 1,0, [8] = LSB, [9] = MSBvoid Aperture (uint16_t val) {// passant d'un valor ADC de 12 bits a un valor d'apertura de 11 bits obertura [8] = (uint8_t) (((val >> 1)) & 0xFF)); obertura [9] = (uint8_t) (((val >> 1) & 0xFF00) >> 8); pControlCharacteristic-> writeValue ((uint8_t *) obertura, 12, cert); }

Pas 3: el circuit

El Circuit
El Circuit

He adjuntat el PDF del meu circuit. També s’adjunten algunes imatges del PCB.

La placa s’alimenta amb micro USB.

Després de rebre el PCB, vaig decidir que volia conduir un LED RGB, de manera que vaig connectar dos WS2812B en sèrie a la sortida "Button Led" (que necessitava alguns pegats de fil a la PCB). Els PCB tenien 8USD amb OSHPark.com.

Podeu veure algunes connexions més al PCB, com ara "adc" que no faig servir i que s'han eliminat dels esquemes adjunts. El pla era utilitzar una roda d’enfocament extern en el passat, però actualment estic perfectament satisfet amb la roda del polze.

Pas 4: Conclusió

Espero que això hagi ajudat.

Tinc algunes actualitzacions futures en ment, com ara utilitzar un codificador rotatiu sense parades difícils. Això requerirà que el controlador obtingui el valor actual del focus o obertura de la càmera i continuï des d'allà. Probablement, cal actualitzar la funció "notificationCallback".

El PCB necessita una actualització per proporcionar els senyals dels LED RGB WS2812B correctament.

Vaig passar molt (un botí) de temps a fer aquest treball, especialment la part BLE. Si això us va ajudar i voleu comprar-me una beguda, això és molt agraït:) Aquest és un enllaç de donació de Paypal:

Recomanat: