Πίνακας περιεχομένων:

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 βήματα (με εικόνες)
Βίντεο: MagicButton4k: super handy bmpcc4k bluetooth remote 2024, Νοέμβριος
Anonim
Image
Image

Πολλοί άνθρωποι μου ζήτησαν να μοιραστώ μερικές λεπτομέρειες σχετικά με τον ασύρματο ελεγκτή μου για το BMPCC4k. Οι περισσότερες ερωτήσεις αφορούσαν τον έλεγχο bluetooth, οπότε θα αναφέρω μερικές λεπτομέρειες σχετικά με αυτό. Υποθέτω ότι είστε εξοικειωμένοι με το περιβάλλον ESP32 Arduino.

Αυτή η έκδοση του τηλεχειριστηρίου μπορεί να ελέγξει την εγγραφή, την εστίαση και το διάφραγμα της κάμερας μέσω bluetooth. Ρίξτε μια ματιά στο βίντεο. Είναι πολύ εύκολο να προσθέσετε περισσότερες λειτουργίες ελέγχου σύμφωνα με το εγχειρίδιο ελέγχου bluetooth του BMPCC4k. Βασικά οτιδήποτε στην κάμερα μπορεί να ελεγχθεί, από όσο έχω δει.

Θα ήταν εύκολο να προσθέσετε μια μονάδα LIDAR για να μετρήσετε την απόσταση ενός θέματος, ώστε να έχετε ένα είδος συστήματος αυτόματης εστίασης… Αν και είναι αμφίβολο αν μπορείτε να εστιάσετε αρκετά ακριβή σε συγκεκριμένες περιοχές, όπως μάτια κ.λπ.…

ΕΝΗΜΕΡΩΣΗ 2020: Έφτιαξα την έκδοση 3.0. Βασίζεται σε έναν δωρεάν περιστρεφόμενο τροχό χρησιμοποιώντας μαγνητικό κωδικοποιητή. Συνδέεται επίσης με τον ακόλουθο κινητήρα εστίασης, ο οποίος βασικά γίνεται μια δεύτερη συσκευή bluetooth (το ESP32 υποστηρίζει πολλαπλές συνδέσεις bluetooth). Το νέο βίντεο το αποδεικνύει.

Εάν θέλετε να παραγγείλετε την έκδοση 3, ρίξτε μια ματιά στον ιστότοπο του MagicButton

Προμήθειες

Οποιαδήποτε μονάδα ESP32 με wifi και bluetooth. Χρησιμοποίησα το TTGO micro32 επειδή είναι μικροσκοπικό:

Ένας τροχός εστίασης, κάθε ποτενσιόμετρο θα έκανε. Χρησιμοποίησα τα παρακάτω επειδή είναι μικροσκοπικά: https://www.aliexpress.com/item/32963061806.html? S… Αυτό το είδος έχει σκληρές στάσεις στο άνω και κάτω όριο. Σε μια μελλοντική έκδοση θα χρησιμοποιήσω έναν περιστροφικό κωδικοποιητή. Με αυτόν τον τρόπο η εστίαση ή το διάφραγμα δεν "πηδάει" στην τρέχουσα ρύθμιση του τροχού όταν μπαίνω σε μια λειτουργία.

Ένα κουμπί rec/mode. Χρησιμοποίησα τα εξής: https://www.aliexpress.com/item/32806223591.html? S…

Άλλα τυπικά εξαρτήματα, όπως αντιστάσεις, καλύμματα,… (βλ. Σχηματικό)

Βήμα 1: Ο κώδικας

Χρησιμοποιώ τη δυνατότητα wifi του ESP32 είτε για σύνδεση σε γνωστό δίκτυο σε λειτουργία AP, είτε όταν βρίσκομαι στο πεδίο, γίνεται σταθμός (STA) στον οποίο μπορώ να συνδεθώ. Με αυτόν τον τρόπο μπορώ να διαμορφώσω τη μονάδα. Δεν θα μπω σε λεπτομέρειες για την ενότητα wifi/ιστοσελίδας, ίσως το προσθέσω σε μεταγενέστερο στάδιο.

Το ESP32 συνδέεται με την κάμερα και γίνεται πελάτης Bluetooth LE. Ο κωδικός bluetooth που περιλαμβάνεται στο πλαίσιο ESP32 του Arduino δεν λειτουργεί με το BMPCC4k. Το Wakwak-koba μας το έχει φτιάξει. Ευχαριστώ Wakwak-koba! Χρησιμοποίησα τη βιβλιοθήκη BLE από εδώ:

github.com/wakwak-koba/arduino-esp32

Παρ 'όλα αυτά, η έκδοση του lib BLE είναι ακόμη υπό ανάπτυξη και η τελευταία έκδοση του BLEUUID.cpp δεν φαίνεται να λειτουργεί αυτήν τη στιγμή, οπότε πάρτε την προηγούμενη "επαληθευμένη" έκδοση αυτού του αρχείου.

Για τα υπόλοιπα, ο περισσότερος κωδικός bluetooth μου είναι πολύ σύμφωνα με τα παραδείγματα BLE που περιλαμβάνονται στο πλαίσιο Arduino:

Ορισμένα BLE UUID και μεταβλητή ορίζουν:

στατικό BLEUUID BlackMagic ("00001800-0000-1000-8000-00805f9b34fb");

στατικό BLEUUID ControlserviceUUID ("291D567A-6D75-11E6-8B77-86F30CA893D3"); στατικό BLEUUID DevInfoServiceControlUUID ("180A"); στατικό BLEUUID ControlcharUUID ("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; στατικό boolean doConnect = 0; συνδεδεμένο στατικό boolean = 0; σάρωση πτητικού = 0; volatileuint32_t pinCode;

Η σάρωση και ο κύριος βρόχος:

class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {

void onResult (BLEAdvertisedDevice advertisedDevice) {Serial.print ("Βρέθηκε διαφημισμένη συσκευή BLE:"); Serial.println (advertisedDevice.toString (). C_str ()); if (advertisedDevice.getScan ()-> stop (); myDevice = νέα BLEAdvertisedDevice (advertisedDevice); doConnect = true; }}}; στατική κενή σάρωσηCompleteCB (BLEScanResults scanResults) {Serial.println ("scanning done"); σάρωση = false? } void loop (void) {if (! Connect && ((uint32_t) (millis () - Timer)> BLE_RESCAN_TIME || (! σάρωση))) {Serial.println ("σάρωση …"); σάρωση = αλήθεια pBLEScan-> έναρξη (BLE_SCAN_TIME, scanCompleteCB); Χρονόμετρο = millis (); } if (doConnect == true) {if (connectToServer ()) {Serial.println ("Είμαστε πλέον συνδεδεμένοι στον διακομιστή BLE."); συνδεδεμενο = αληθινο? } else {Serial.println ("Αποτύχαμε να συνδεθούμε στον διακομιστή. δεν θα κάνουμε τίποτα περισσότερο."); } doConnect = false; }}

Σύνδεση με την κάμερα:

bool connectToServer () {

Serial.print ("Δημιουργία σύνδεσης με"); Serial.println (myDevice-> getAddress (). ToString (). C_str ()); BLEDevice:: setEncryptionLevel (ESP_BLE_SEC_ENCRYPT); BLEDevice:: setSecurityCallbacks (νέα 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 (νέο MyClientCallback ()); pClient-> σύνδεση (myDevice). Serial.println (" - Συνδέθηκε με διακομιστή"); BLEDevice:: setMTU (BLEDevice:: getMTU ()); // ΥΠΟΒΟΛΗ ΚΑΜΕΡΑΣ ΜΟΝΤΕΛΟ BLERemoteService *pRemoteService = pClient-> getService (DevInfoServiceControlUUID); if (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 value = pRemoteCamModelCharacteristic-> readValue (); Serial.print ("Η κάμερα είναι"); Serial.println (value.c_str ()); if (CamModel! = value.c_str ()) {Serial.print (" - Η κάμερα δεν είναι BMPCC4k"); πρέπει να αποτύχει? } // OBTAIN CONTROL pRemoteService = pClient-> getService (ControlserviceUUID); if (pRemoteService == nullptr) {Serial.print (" - Αποτυχία λήψης υπηρεσίας κάμερας"); Serial.println (ControlserviceUUID.toString (). C_str ()); πρέπει να αποτύχει? } BLERemoteCharacteristic *pRemoteClientNameCharacteristic = pRemoteService-> getCharacteristic (ClientNamecharUUID); if (pRemoteClientNameCharacteristic! = nullptr) {pRemoteClientNameCharacteristic-> writeValue (MyName.c_str (), MyName.length ()); } pControlCharacteristic = pRemoteService-> getCharacteristic (ControlcharUUID); if (pControlCharacteristic == nullptr) {Serial.print (" - Αποτυχία λήψης χαρακτηριστικού ελέγχου"); Serial.println (ControlcharUUID.toString (). C_str ()); πρέπει να αποτύχει? } pNotifCharacteristic = pRemoteService-> getCharacteristic (NotifcharUUID); if (pNotifCharacteristic! = nullptr) // && pNotifCharacteristic-> canIndicate ()) {Serial.println (" - εγγραφή στην ειδοποίηση"); const uint8_t indicOO = {0x2, 0x0}; pNotifCharacteristic-> registerForNotify (notifyCallback, false); pNotifCharacteristic-> getDescriptor (BLEUUID ((uint16_t) 0x2902))-> writeValue ((uint8_t*) ένδειξηOn, 2, true); } return true? fail: pClient-> disconnect (); επιστροφή ψευδής? }

Η συνδεδεμένη/αποσυνδεδεμένη επανάκληση:

κλάση MyClientCallback: public BLEClientCallbacks {

void onConnect (BLEClient *pclient) {Serial.println ("Είμαστε συνδεδεμένοι."); } void onDisconnect (BLEClient *pclient) {Connect = false; pclient-> disconnect (); Serial.println ("Αποσυνδεθήκαμε."); }};

Το μέρος του κωδικού PIN:

Στην τρέχουσα έκδοσή μου, μπορώ να εισαγάγω τον κωδικό πρόσβασης μέσω της διεπαφής ιστού, αλλά αυτές είναι λεπτομέρειες wifi/ιστοσελίδας που θα μπορούσα να προσθέσω αργότερα.

κλάση MySecurity: public BLESecurityCallbacks

{uint32_t onPassKeyRequest () {Serial.println ("- PLEASE ENTER 6 DIGIT PIN (τέλος με ENTER):"); pinCode = 0; char ch? do {while (! Serial.available ()) {delay (1); } ch = Serial.read (); εάν (ch> = '0' && ch <= '9') {pinCode = pinCode *10+ (ch -'0 '); Serial.print (ch); }} while ((ch! = '\ n')); επιστροφή pinCode; } void onPassKeyNotify (uint32_t pass_key) {ESP_LOGE (LOG_TAG, "The password key Notification number:%d", pass_key); } bool onConfirmPIN (uint32_t pass_key) {ESP_LOGI (LOG_TAG, "Ο κωδικός πρόσβασης ΝΑΙ/ΟΧΙ αριθμός:%d", pass_key); vTaskDelay (5000); επαναλαμβανόμενος? } bool onSecurityRequest () {ESP_LOGI (LOG_TAG, "Αίτημα ασφαλείας"); επαναλαμβανόμενος? } void onAuthenticationComplete (esp_ble_auth_cmpl_t auth_cmpl) {Serial.print ("pair status ="); Serial.println (auth_cmpl.success); }};

Ειδοποίηση BLE:

Η κάμερα ειδοποιεί τους πελάτες της BLE για τυχόν αλλαγές στην κάμερα, συμπεριλαμβανομένου του πότε η κάμερα ξεκινά και σταματά την εγγραφή. Αυτός ο κωδικός αλλάζει τη λυχνία μου όταν ξεκινά/σταματά την εγγραφή.

static void notifyCallback (BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t*pData, size_t length, bool isNotify) {// BMPCC4k Μορφή μηνύματος BLE: // η επαναφορά είναι 255 9 0 0 10 1 1 2 2 0 64 0 2 // η απενεργοποίηση είναι 255 9 0 0 10 1 1 2 0 0 64 0 2if (μήκος == 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; }}}

Βήμα 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; else record [8] = 2; pControlCharacteristic-> writeValue ((uint8_t*) record, 16, true); }

Εστίαση:

Η κάμερα αναμένει έναν αριθμό 11 bit, που κυμαίνεται από κοντινή έως μακρινή εστίαση. Σας συμβουλεύω να βάλετε ένα φίλτρο στην τιμή ADC, διαφορετικά η εστίαση μπορεί να εκνευριστεί νευρικά.

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) {// μετάβαση από 12bit τιμή ADC σε εστίαση 11bit εστίασης [8] = (uint8_t) ((((val> > 1) & 0xFF)); εστίαση [9] = (uint8_t) (((val >> 1) & 0xFF00) >> 8); pControlCharacteristic-> writeValue ((uint8_t*) focus, 12, true); }

Ανοιγμα:

Η κάμερα αναμένει έναν αριθμό 11 bit, που κυμαίνεται από χαμηλή έως υψηλή τιμή διαφράγματος. Σας συμβουλεύω να βάλετε ένα φίλτρο στην τιμή 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) {// μετάβαση από μια τιμή 12bit ADC σε μια τιμή διαφράγματος 11bit [8] = (uint8_t) ((((val >> 1) & 0xFF)); διάφραγμα [9] = (uint8_t) (((val >> 1) & 0xFF00) >> 8); pControlCharacteristic-> writeValue ((uint8_t*) διάφραγμα, 12, true); }

Βήμα 3: Το κύκλωμα

Το Κύκλωμα
Το Κύκλωμα

Έχω επισυνάψει το PDF του κυκλώματός μου. Επισυνάπτονται επίσης μερικές φωτογραφίες του PCB.

Η πλακέτα τροφοδοτείται με micro USB.

Μετά τη λήψη του PCB αποφάσισα ότι ήθελα να οδηγήσω ένα LED RGB, έτσι συνέδεσα δύο σειρές WS2812B στην έξοδο "Button Led" (που χρειάζονταν ορισμένα μπαλώματα σύρματος στο PCB). Τα PCB ήταν 8USD με το OSHPark.com.

Μπορείτε να δείτε μερικές ακόμη συνδέσεις στο PCB όπως "adc" που δεν χρησιμοποιώ και οι οποίες αφαιρέθηκαν από τα συνημμένα σχήματα. Το σχέδιο ήταν να χρησιμοποιήσω έναν εξωτερικό τροχό εστίασης στο παρελθόν, αλλά προς το παρόν είμαι απόλυτα ευχαριστημένος με τον μικρό αντίχειρα.

Βήμα 4: Συμπέρασμα

Ελπίζω να βοήθησε αυτό.

Έχω στο μυαλό μου κάποιες μελλοντικές ενημερώσεις, όπως η χρήση περιστροφικού κωδικοποιητή χωρίς σκληρές στάσεις. Αυτό θα απαιτήσει από τον ελεγκτή να πάρει την τρέχουσα τιμή της εστίασης ή του διαφράγματος από την κάμερα και να συνεχίσει από εκεί. Η λειτουργία "notifyCallback" πρέπει να ενημερωθεί για αυτό πιθανότατα.

Το PCB χρειάζεται μια ενημέρωση για να παρέχει σωστά τα σήματα για τις λυχνίες LED WS2812B RGB.

Ξόδεψα πολύ (μια χαλαρή) ώρα για να φτιάξω αυτό το έργο, ειδικά το κομμάτι του BLE. Εάν αυτό σας βοήθησε και θέλετε να μου αγοράσετε ένα ποτό, εκτιμάται πολύ:) Αυτός είναι ένας σύνδεσμος δωρεάς Paypal:

Συνιστάται: