Spisu treści:

Kamera PANTILT z ESP32: 9 kroków
Kamera PANTILT z ESP32: 9 kroków

Wideo: Kamera PANTILT z ESP32: 9 kroków

Wideo: Kamera PANTILT z ESP32: 9 kroków
Wideo: Camera Car With Pan Tilt Control | ESP32Cam 2024, Lipiec
Anonim
Image
Image
PANTILT Kamera z ESP32
PANTILT Kamera z ESP32

Dziś przedstawię PAN TILT, czyli urządzenie umożliwiające ruch kamery w kierunkach góra, dół i boki. Sam wyprodukowałem to urządzenie poprzez części drukowane 3D, używając dwóch serwomechanizmów i ESP32, co umożliwia sterowanie tym mechanizmem przez WiFi. Weźmy zatem odczyty z wykorzystaniem kanałów AD ESP32, a także operację analogową z wykorzystaniem sterownika LED_PWM. Stosujemy również kontrolę nad połączeniem TCP/IP.

Na filmiku widać, że mam ESP32 odczytujący wartości z dwóch potencjometrów, które są przesyłane (przez WiFi) do innego ESP32. Jest podłączony do dwóch serwosilników. Kamera porusza się (i jest przymocowana do PAN TILT) w kierunku w górę, w dół lub na boki, w zależności od kontroli, jaką wykonujesz przez garnki.

Link do projektu druku 3D PAN TILT można znaleźć tutaj:

Krok 1: Wykorzystane zasoby

Wykorzystane zasoby
Wykorzystane zasoby

• Wiele zworek do połączenia

• Dwa węzłowe MCU ESP32

• Dwa kable USB do ESP32

• Kamera internetowa do kontroli

• Dwa potencjometry kontrolne

• Protoboard

• Źródło dla serw

Krok 2: NodeMCU ESP32S - Pinout

NodeMCU ESP32S - Pinout
NodeMCU ESP32S - Pinout

Krok 3: Urządzenia peryferyjne ESP32

Urządzenia peryferyjne ESP32
Urządzenia peryferyjne ESP32

Peryferia PWM ESP32 posiada dwa peryferia zdolne do generowania sygnałów PWM. Obejmują one silnik modulatora szerokości impulsu (MCPWM) przeznaczony do sterowania mocą i silnikiem oraz LED_PWM, opracowany do sterowania intensywnością diod LED. Ale można ich również używać w sposób ogólny.

Wykorzystamy LED_PWM, który może generować 16 niezależnych kanałów PWM z konfigurowalnymi okresami i cyklami pracy. Ma do 16 bitów rozdzielczości.

Krok 4: Sterowanie serwosilnikiem PWM

Sterowanie silnikiem serwo PWM
Sterowanie silnikiem serwo PWM

Sterowanie silnikiem serwo odbywa się poprzez regulację modulacji szerokości impulsu kwadratu o określonej częstotliwości.

W przypadku używanego serwomechanizmu (jak i większości) częstotliwość wynosi 50 Hz. Również szerokość od 1 do 2 ms długości impulsu określa położenie kątowe serwomechanizmu.

Przekierujemy kanał 0 z LED_PWM do GPIO13, a kanał 1 do GPIO12, wykorzystując te informacje do wykonania sterowania.

Krok 5: Przechwytywanie analogowe

Przechwytywanie analogowe
Przechwytywanie analogowe

Urządzenie peryferyjne do konwersji analogowo-cyfrowej

ESP32 posiada konwertery analogowo-cyfrowe, które można zastosować w maksymalnie 18 kanałach, ale tylko w GPIO z obsługą analogową.

Przyłożone napięcie nie może przekraczać zakresu od 0 do 3V.

Przeprowadzona konwersja nie utrzymuje stałego błędu dla wszystkich próbkowanych napięć, a to wszystko zależy od skonfigurowanego zakresu. Dla zakresu 150mV przy 2,450V, w bardziej krytycznych zastosowaniach wymagana jest kontrola zachowania.

Do przechwytywania użyjemy potencjometru 10k jako dzielnika napięcia. Przechwytywanie zostanie wykonane w kanałach ADC0 i ADC3, dostępnych przez GPIO36 i GPIO39.

Krok 6: Obwód - serwer i klient

Obwód - serwer i klient
Obwód - serwer i klient

Krok 7: Kod źródłowy punktu dostępowego i serwera

Sprawozdania

Dołączam bibliotekę WiFi i definiuję kilka zmiennych.

#include // inclusão da biblioteca WiFi const int freq = 50; //częstotliwość do PWM const int canal_A = 0; //primeiro canal do controlador LED_PWM const int canal_B = 1; //segundo canal do controlador LED_PWM const int resolucao = 12; //Resolução usado no controlador LED_PWM const int pin_Atuacao_A = 13; //Pino para onde o canal 0 será redirecionado const int pin_Atuacao_B = 12; //Pino para onde o canal 1 será przekierowanie const char* ssid = "ESP32ap"; //constante com o SSID do WiFi do ponto de acesso ESP32 const char* password = "12345678"; //senha para confirmação de conexão no ponto de acesso const int port = 2; //porta na qual o servidor receberá as conexões int ciclo_A = 0; //variável que receberá o ciclo de atuação do canal A int ciclo_B = 0; //variável que receberá o ciclo de atuação do canal Serwer (port) WiFiServer; //declaração do objeto adres IP serwera mójIP; //declaração da variável de IP

Ustawiać ()

Tutaj definiujemy piny wyjściowe. Ustawiamy kanały na żądaną częstotliwość i ustawiamy wartość PWM.

void setup(){ pinMode(pin_Atuacao_A, WYJŚCIE); //definiuj pino de atuação A como saída pinMode(pin_Atuacao_B, OUTPUT); //definiuj pino de atuação B como saída ledcSetup(canal_A, freq, resolucao); //Dostosuj kanał 0 do częstotliwości 50 Hz i rozdzielczość 12 bitów ledcSetup(canal_B, freq, resolucao); //Dostosuj kanał 1 do częstotliwości 50 Hz i rozdzielczość 12 bitów ledcAttachPin(pin_Atuacao_A, canal_A); //przekierowanie o kanał 0 para o pino 13 ledcAttachPin(pin_Atuacao_B, canal_B); //przekierowanie o canal 1 para o pino 12 ledcWrite(canal_A, ciclo_A); //określ wartość PWM dla 0 ledcWrite(canal_B, ciclo_B); //definiuj męstwo do PWM dla 0

Uruchomiliśmy serial, punkt dostępowy z SSID ESP32ap i hasłem. Następnie otrzymujemy adres IP serwera i uruchamiamy serwer.

Serial.początek(115200); //inicjuj Serial Serial.println("Początek dostępu: " + String(ssid)); //mensagem WiFi.softAP (ssid, hasło); //inicjant o ponto de acesso com SSID ESP32ap e senha 12345678 Serial.println("Obtendo IP"); //mensagem myIP = WiFi.softAPIP (); //obtendo o IP do servidor (como não foi configurado deverá ser o padrão de fábrica) Serial.println("IP: " + WiFi.localIP()); //mensagem Serial.println("Początkowy serwer: " + String(port)); //mensagem server.begin(); //inicjuj serwer }

Pętla ()

W Loop pierwszą rzeczą, którą zrobimy, jest utworzenie instancji klienta, połączenie i powiązanie ze zmienną klienta. Sprawdź, czy klient jest podłączony. Jeśli tak, uruchamiamy zmienną, która otrzyma dane. Dopóki połączenie jest nawiązane i jeśli dane są odbierane, odczytujemy znaki dla zmiennej c. Na koniec łączymy c w zmiennej data.

void loop() { Klient WiFiClient = server.available(); //połącz klienta, skojarz zmienną klientelę if (cliente.connected()) { //połącz klienta String dados = ""; //inicia a variável que receberá os dados Serial.println("Połączenie klienta."); //mensagem while (cliente.connected()) { //włącz połączenie estabelecida if (cliente.available()) { //e se houver dados a receber char c = cliente.read(); //leia os caracteres para a variável c dados = dados + c; //concatene c na variável dados

Jeśli zostanie odebrany znak nowej linii, szukamy indeksu znaku „,” w ciągu w danych. Otrzymujemy podciągi aż do momentu tuż przed przecinkiem, a następnie konwertujemy je na liczbę całkowitą. Ustawiamy PWM kanałów A i B. Czyścimy zmienną.

if (c == '\n') { //se um caracter de nova linha for recebido int virgula = dados.indexOf(', '); //pozyskaj pelo índice do caracter ', ' na string em dados ciclo_A = (dados.substring(0, virgula)).toInt(); //uzyskaj substring até antes da vírgula e converta para inteiro ciclo_B = dados.substring(virgula + 1, dados.length()).toInt();//obtenha substring após a vírgula e converta para inteiro ledcWrite(canal_A, ciclo_A); //Ajusta o PWM do kanału A ledcWrite(canal_B, ciclo_B); //Ajusta o PWM do kanału B dados = ""; //Limpa a variável } } } }

Jeśli klient się rozłączy, potwierdzamy zakończenie połączenia. Czekamy chwilę i wypisujemy "Brak połączenia z klientem". Następnie czekamy kolejną sekundę przed ponownym uruchomieniem.

// caso o cliente se desconecte, Confirma o fim da conexão delay(50); //ochrona chwilowego klienta.stop(); Serial.println("Połączone klienty Nenhum."); //opóźnienie komunikatu(1000); //aguarda um segundo antes de reiniciar }

Krok 8: Kod źródłowy klienta

Sprawozdania

Ponownie włączyliśmy bibliotekę WiFi, tym razem na kliencie. Definiujemy również zmienne.

#include const char* ssid = "ESP32ap"; //SSID do ponto de acesso ESP32 const char* password = "12345678"; //Senha para acessar o ponto de acesso const uint16_t port = 2; //Porta de escuta do servidor const char * host = "192.168.4.1"; //endereço IP do servidor const int pin_Leitura_A = 36; //GPIO de leitura do ADC0 const int pin_Leitura_B = 39; //GPIO de leitura do ADC3 int ciclo_A = 0; //variável que receberá o valor do ciclo do PWM A int ciclo_B = 0; //Variável que receberá o valor to ciclo do PWM B WiFiClient cliente; //declaração do objeto cliente

Ustawiać ()

Definiujemy GPIO jako wejście, uruchamiamy port szeregowy i łączymy się z punktem dostępowym.

void setup(){ pinMode(pin_Leitura_A, INPUT); //zdefiniuj GPIO como entrada pinMode(pin_Leitura_B, INPUT); //definiuj GPIO como entrada Serial.begin(115200); //inicja komunikacji szeregowej WiFi.begin (ssid, hasło); //conecta ao ponto de acesso }

Pętla ()

W tej pętli połączymy się z serwerem, czyli z drugim ESP.

void loop(){ //se não conectado ao ponto de acesso, tenta se conectar while (WiFi.status() != WL_CONNECTED) { Serial.println(String(millis()) + " - Połącz bez WiFi " + ssid + „…”); //mensagem WiFi.begin(SSid, hasło); opóźnienie (2000); } Serial.println(String(millis()) + " - Połącz…"); //mensagem //se não conectado ao servidor, tenta se conectar while (!cliente.connect(host, port)) { Serial.println(String(millis()) + " - Połącz bez serwera " + host + ":" + port + „…”); //opóźnienie komunikatu(1000); }

W tym kroku, będąc podłączonym do serwera, wykonujemy zmienne do przechowywania odczytu ADC0 i ADC3. Przeprowadziliśmy również odczyt 500 próbek i uśredniliśmy odczyty. Zmapowaliśmy odczyt, aby stworzyć prawidłowy czas trwania kontroli serwomechanizmów, połączyć go i wysłać na serwer.

//enquanto estiver conectado ao servidor while (cliente.connected()) { int leitura_A = 0; //variável para armazenar a leitura do ADC0 int leitura_B = 0; //variável para armazenar a leitura do ADC3 int amostras = 500; //número de amostras int contador = 0; //contador de amostras while (contador < amostras) { //acumua várias leituras leitura_A = leitura_A + analogRead(pin_Leitura_A); leitura_B = leitura_B + odczyt analogowy(pin_Leitura_B); contador++; } leitura_A = leitura_A / amostras; //média das leituras leitura_B = leitura_B / amostras; ciclo_A = mapa(leitura_A, 0, 4095, 140, 490); //mapeia a leitura para criar a duração correta para controle do servo ciclo_B = map(leitura_B, 0, 4095, 140, 490); //mapeia a leitura para criar a duração correta para controle do servo //concatena e envia para o servidor cliente.println(String(ciclo_A) + ", " + String(ciclo_B)); }

Wreszcie, jeśli nie jest połączony, upewniamy się, że połączenie zostało zakończone, wyświetlając równoważny komunikat.

//se não coonectado, garante que a conexão foi finalizada cliente.stop(); Serial.println(String(millis()) + " - klient usunięty…"); //komunikat }

Krok 9: Pliki

Pobierz pliki:

PDF

JA NIE

Zalecana: