Índice:
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:35
Muitas pessoas me pediram para compartilhar alguns detalhes sobre meu controlador sem fio para o BMPCC4k. A maioria das perguntas era sobre o controle do bluetooth, então mencionarei alguns detalhes sobre isso. Presumo que você esteja familiarizado com o ambiente ESP32 Arduino.
Esta versão do controle remoto pode controlar a gravação, o foco e a abertura da câmera via bluetooth. Dê uma olhada no vídeo. É muito fácil adicionar mais funções de controle de acordo com o manual de controle bluetooth do BMPCC4k. Basicamente, qualquer coisa na câmera pode ser controlada, pelo que vi.
Seria uma etapa fácil adicionar um módulo LIDAR para medir a distância de um objeto, para que você possa obter algum tipo de sistema de foco automático … Embora seja questionável se você pode obter um foco preciso o suficiente em áreas específicas, como olhos, etc …
ATUALIZAÇÃO 2020: Fiz a versão 3.0. É baseado em uma roda giratória livre usando um codificador magnético. Ele também se conecta ao meu motor de follow focus, que basicamente se torna um segundo dispositivo bluetooth (o ESP32 suporta múltiplas conexões bluetooth). O novo vídeo demonstra isso.
Se você gostaria de solicitar a versão 3, dê uma olhada no site MagicButton
Suprimentos
Qualquer módulo ESP32 com wi-fi e bluetooth. Usei o TTGO micro32 porque ele é minúsculo:
Uma roda de foco, qualquer potenciômetro serviria. Usei o seguinte porque é minúsculo: https://www.aliexpress.com/item/32963061806.html? S… Esse tipo tem paradas rígidas nos limites superior e inferior. Em uma versão futura, usarei um codificador rotativo. Desta forma, o foco ou a abertura não "pula" para a configuração atual da roda quando entro em um modo.
Um botão rec / modo. Usei o seguinte: https://www.aliexpress.com/item/32806223591.html? S…
Outros componentes padrão, como resistores, tampas, … (consulte o esquema)
Etapa 1: O Código
Eu uso o recurso wi-fi do ESP32 para me conectar a uma rede conhecida no modo AP ou, quando estou em campo, ele se torna uma estação (STA) à qual posso me conectar. Assim posso configurar o módulo. Não vou entrar em detalhes sobre a seção wi-fi / página da web, posso adicionar isso em um estágio posterior.
O ESP32 se conecta à câmera e se torna um cliente Bluetooth LE. O código bluetooth incluído na estrutura ESP32 do Arduino não funciona com o BMPCC4k. Wakwak-koba consertou isso para nós. Obrigado Wakwak-koba! Usei a biblioteca BLE daqui:
github.com/wakwak-koba/arduino-esp32
No entanto, essa versão do BLE lib ainda está em desenvolvimento e a versão mais recente do BLEUUID.cpp parece não funcionar no momento, então pegue a versão anterior "verificada" deste arquivo.
De resto, a maior parte do meu código bluetooth é muito semelhante aos exemplos BLE incluídos na estrutura do Arduino:
Alguns BLE UUID e variáveis definem:
estático BLEUUID BlackMagic ("00001800-0000-1000-8000-00805f9b34fb");
estático BLEUUID ControlserviceUUID ("291D567A-6D75-11E6-8B77-86F30CA893D3"); estático BLEUUID DevInfoServiceControlUUID ("180A"); BLEUUID estático ControlcharUUID ("5DD3465F-1AEE-4299-8493-D2ECA2F8E1BB"); estático BLEUUID NotifcharUUID ("B864E140-76A0-416A-BF30-5876504537D9"); BLEUUID estático ClientNamecharUUID ("FFAC0C52-C9FB-41A0-B063-CC76282EB89C"); estático BLEUUID CamModelcharUUID ("2A24"); estático BLEScan * pBLEScan = BLEDevice:: getScan (); estático BLEAddress * pServerAddress; static BLEAdvertisedDevice * myDevice; static BLERemoteCharacteristic * pControlCharacteristic; static BLERemoteCharacteristic * pNotifCharacteristic; static boolean doConnect = 0; booleano estático conectado = 0; varredura de volatilebool = 0; volatileuint32_t pinCode;
A varredura e o loop principal:
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult (BLEAdvertisedDevice advertisedDevice) {Serial.print ("Dispositivo anunciado BLE encontrado:"); Serial.println (advertisedDevice.toString (). C_str ()); if (advertisedDevice.haveServiceUUID () && advertisedDevice.getServiceUUID (). equals (BlackMagic)) {Serial.print ("Nosso dispositivo foi encontrado!"); advertisedDevice.getScan () -> stop (); myDevice = new BLEAdvertisedDevice (advertisedDevice); doConnect = true; }}}; static void scanCompleteCB (BLEScanResults scanResults) {Serial.println ("digitalização concluída"); digitalização = falso; } void loop (void) {if (! connected && ((uint32_t) (millis () - Timer)> BLE_RESCAN_TIME || (! scanning))) {Serial.println ("scanning…"); digitalização = verdadeiro; pBLEScan-> iniciar (BLE_SCAN_TIME, scanCompleteCB); Temporizador = milis (); } if (doConnect == true) {if (connectToServer ()) {Serial.println ("Agora estamos conectados ao servidor BLE."); conectado = verdadeiro; } else {Serial.println ("Falha ao conectar ao servidor; não há mais nada que faremos."); } doConnect = false; }}
Conectando-se à câmera:
bool connectToServer () {
Serial.print ("Formando uma conexão com"); Serial.println (meuDispositivo-> getAddress (). ToString (). C_str ()); BLEDevice:: setEncryptionLevel (ESP_BLE_SEC_ENCRYPT); BLEDevice:: setSecurityCallbacks (new MySecurity ()); BLESecurity * pSecurity = novo 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-> conectar (meuDispositivo); Serial.println ("- Conectado ao servidor"); BLEDevice:: setMTU (BLEDevice:: getMTU ()); // OBTENHA O MODELO DE CÂMERA BLERemoteService * pRemoteService = pClient-> getService (DevInfoServiceControlUUID); if (pRemoteService == nullptr) {Serial.print ("- Falha ao obter o serviço de informações do dispositivo"); Serial.println (DevInfoServiceControlUUID.toString (). C_str ()); goto fail; } Serial.println ("- Lendo informações do dispositivo"); // Obtenha uma referência para a característica no serviço do servidor BLE remoto. BLERemoteCharacteristic * pRemoteCamModelCharacteristic = pRemoteService-> getCharacteristic (CamModelcharUUID); if (pRemoteCamModelCharacteristic == nullptr) {Serial.print ("- Falha ao encontrar o modelo da câmera"); Serial.println (CamModelcharUUID.toString (). C_str ()); goto fail; } // Leia o valor da característica. std:: string value = pRemoteCamModelCharacteristic-> readValue (); Serial.print ("Câmera é"); Serial.println (valor.c_str ()); if (CamModel! = value.c_str ()) {Serial.print ("- A câmera não é BMPCC4k"); goto fail; } // OBTENHA O CONTROLE pRemoteService = pClient-> getService (ControlserviceUUID); if (pRemoteService == nullptr) {Serial.print ("- Falha ao obter o serviço da câmera"); Serial.println (ControlserviceUUID.toString (). C_str ()); goto fail; } BLERemoteCharacteristic * pRemoteClientNameCharacteristic = pRemoteService-> getCharacteristic (ClientNamecharUUID); if (pRemoteClientNameCharacteristic! = nullptr) {pRemoteClientNameCharacteristic-> writeValue (MyName.c_str (), MyName.length ()); } pControlCharacteristic = pRemoteService-> getCharacteristic (ControlcharUUID); if (pControlCharacteristic == nullptr) {Serial.print ("- Falha ao obter característica de controle"); Serial.println (ControlcharUUID.toString (). C_str ()); goto fail; } pNotifCharacteristic = pRemoteService-> getCharacteristic (NotifcharUUID); if (pNotifCharacteristic! = nullptr) // && pNotifCharacteristic-> canIndicate ()) {Serial.println ("- assinando a notificação"); const uint8_t identificationOn = {0x2, 0x0}; pNotifCharacteristic-> registerForNotify (notificarCallback, false); pNotifCharacteristic-> getDescriptor (BLEUUID ((uint16_t) 0x2902)) -> writeValue ((uint8_t *) indicaçãoOn, 2, verdadeiro); } return true; falha: pClient-> desconectar (); retorna falso; }
O retorno de chamada conectado / desconectado:
class MyClientCallback: public BLEClientCallbacks {
void onConnect (BLEClient * pclient) {Serial.println ("Estamos conectados."); } void onDisconnect (BLEClient * pclient) {conectado = falso; pclient-> desconectar (); Serial.println ("Desconectamos."); }};
A parte do código PIN:
Na minha versão atual, posso inserir o código PIN através da interface da web, mas esses são detalhes de wi-fi / página da web que devo adicionar mais tarde.
classe MySecurity: public BLESecurityCallbacks
{uint32_t onPassKeyRequest () {Serial.println ("- INSIRA O PIN DE 6 DÍGITOS (termine com ENTER):"); 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')); return pinCode; } void onPassKeyNotify (uint32_t pass_key) {ESP_LOGE (LOG_TAG, "O número de notificação da senha:% d", pass_key); } bool onConfirmPIN (uint32_t pass_key) {ESP_LOGI (LOG_TAG, "A senha SIM / NÃO número:% d", pass_key); vTaskDelay (5000); returntrue; } bool onSecurityRequest () {ESP_LOGI (LOG_TAG, "Solicitação de segurança"); returntrue; } void onAuthenticationComplete (esp_ble_auth_cmpl_t auth_cmpl) {Serial.print ("status do par ="); Serial.println (auth_cmpl.success); }};
Notificação BLE:
A câmera notifica seus clientes BLE sobre quaisquer alterações na câmera, incluindo quando a câmera inicia e pára de gravar. Este código alterna meu LED quando ele inicia / pára a gravação.
static void NoticeCallback (BLERemoteCharacteristic * pBLERemoteCharacteristic, uint8_t * pData, size_t length, bool isNotify) {// BMPCC4k formato de mensagem BLE: // rec on é 255 9 0 0 10 1 1 2 2 0 64 0 2 // rec off é 255 9 0 0 10 1 1 2 0 0 64 0 2if (length == 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; }}}
Etapa 2: O Código Parte 2
Esta é a parte que realmente envia os comandos para a câmera.
Gravação:
registro uint8_t = {255, 9, 0, 0, 10, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 0 = OFF, 2 = ON, [8] void Record (boolean RecOn) {if (! RecOn) record [8] = 0; senão registro [8] = 2; pControlCharacteristic-> writeValue ((uint8_t *) registro, 16, verdadeiro); }
Concentrando:
A câmera espera um número de 11 bits, variando de foco próximo a distante. Aconselho colocar um filtro em seu valor de ADC, caso contrário, o foco pode ficar nervosamente instável.
foco uint8_t = {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) {// indo de um valor ADC de 12 bits para o foco de valor de 11 bits [8] = (uint8_t) (((val> > 1) & 0xFF)); foco [9] = (uint8_t) (((val >> 1) & 0xFF00) >> 8); pControlCharacteristic-> writeValue ((uint8_t *) focus, 12, true); }
Abertura:
A câmera espera um número de 11 bits, variando de um valor de abertura baixo a alto. Aconselho colocar um filtro em seu valor de ADC, caso contrário, o valor de abertura pode ficar nervosamente instável.
abertura uint8_t = {255, 6, 0, 0, 0, 3, 128, 0, 0, 0, 0, 0}; // 0,0… 1,0, [8] = LSB, [9] = MSBvoid Abertura (uint16_t val) {// indo de um valor ADC de 12 bits para a abertura do valor de 11 bits [8] = (uint8_t) (((val >> 1) & 0xFF)); abertura [9] = (uint8_t) (((val >> 1) & 0xFF00) >> 8); pControlCharacteristic-> writeValue ((uint8_t *) abertura, 12, verdadeiro); }
Etapa 3: o circuito
Anexei o PDF do meu circuito. Algumas fotos do PCB também estão anexadas.
A placa é alimentada com micro USB.
Depois de receber a placa de circuito impresso, decidi que queria acionar um LED RGB, então conectei dois WS2812B em série na saída "LED de botão" (que precisava de alguns patches de fio na placa de circuito impresso). O PCB foi 8USD com OSHPark.com.
Você pode ver mais algumas conexões no PCB, como "adc", que não estou usando e que foram removidas dos esquemas em anexo. O plano era usar um botão giratório externo no passado, mas atualmente estou perfeitamente feliz com o botão giratório.
Etapa 4: Conclusão
Espero que tenha ajudado.
Tenho em mente algumas atualizações futuras, como o uso de um codificador rotativo sem paradas bruscas. Isso exigirá que o controlador obtenha o valor atual do foco ou abertura da câmera e continue a partir daí. A função "notificarCallback" provavelmente precisa ser atualizada para isso.
O PCB precisa de uma atualização para fornecer os sinais para os LEDs RGB WS2812B corretamente.
Passei muito (muuuuito) tempo fazendo esse trabalho, especialmente a parte BLE. Se isso te ajudou e você quer me pagar uma bebida, isso é muito apreciado:) Este é um link de doação do Paypal:
Recomendado:
O controle remoto da TV se torna um controle remoto de RF -- NRF24L01 + Tutorial: 5 etapas (com imagens)
O controle remoto da TV se torna um controle remoto RF || NRF24L01 + Tutorial: Neste projeto vou mostrar como usei o popular IC nRF24L01 + RF para ajustar o brilho de uma faixa de LED sem fio por meio de três botões inúteis de um controle remoto de TV. Vamos começar
Carro com controle remoto - controlado com o controle sem fio do Xbox 360: 5 etapas
Carro com controle remoto - controlado com o controle sem fio do Xbox 360: Estas são as instruções para construir seu próprio carro com controle remoto, controlado com um controle sem fio do Xbox 360
Faça um mini teclado sem fio com o controle remoto da TV: 10 etapas (com imagens)
Faça um mini teclado sem fio com o controle remoto da TV: Você já pensou em fazer um teclado sem fio hackeando o controle remoto da TV? Portanto, neste manual estou explicando como você pode construir um mini teclado sem fio barato. Este projeto utiliza comunicação IR (infravermelho) para criar uma rede sem fio personalizada
Interruptor remoto '' Botão mágico '': 3 etapas (com imagens)
Interruptor remoto '' Magic Button '': PROBLEMA: O painel de luz LED (faça você mesmo - claro!) Instalado no teto da minha oficina / garagem está conectado a uma tomada elétrica no teto. Eu precisava de alguma forma de ligá-lo e desligá-lo remotamente de onde os interruptores de luz principais estão localizados. SOLUÇÃO:
Transforme uma campainha sem fio em um interruptor de alarme sem fio ou botão liga / desliga: 4 etapas
Transforme uma campainha sem fio em um interruptor de alarme sem fio ou botão liga / desliga: recentemente construí um sistema de alarme e o instalei em minha casa. Usei interruptores magnéticos nas portas e os conectei através do sótão. As janelas eram outra história e fiação direta não era uma opção. Eu precisava de uma solução sem fio e isso é