mirror of
https://github.com/IS1DI/x0gp.git
synced 2026-07-16 20:47:55 +00:00
- Add initial versions of hardware bills of materials (BOM v1-v4), shopping lists, plan, and assembly guides. - Add STL models for 3D-printing the 1/27 scale OpenRC F1 car parts. - Add Blender 3D project files (.blend) and camera renders of the car design iterations. - Add ESP32 client firmware source (client.ino) for handling video streaming and car controls. - Ignore Blender backup files (*.blend1, *.blend2) and IDE directories.
140 lines
4.1 KiB
Arduino
140 lines
4.1 KiB
Arduino
#include "esp_camera.h"
|
|
#include <WiFi.h>
|
|
#include <WiFiUdp.h>
|
|
|
|
// Конфигурация пинов (пример для Seeed Studio XIAO ESP32S3 Sense)
|
|
#define PWDN_GPIO_NUM -1
|
|
#define RESET_GPIO_NUM -1
|
|
#define XCLK_GPIO_NUM 10
|
|
#define SIOD_GPIO_NUM 40
|
|
#define SIOC_GPIO_NUM 39
|
|
#define Y9_GPIO_NUM 48
|
|
#define Y8_GPIO_NUM 47
|
|
#define Y7_GPIO_NUM 13
|
|
#define Y6_GPIO_NUM 14
|
|
#define Y5_GPIO_NUM 12
|
|
#define Y4_GPIO_NUM 11
|
|
#define Y3_GPIO_NUM 17
|
|
#define Y2_GPIO_NUM 16
|
|
#define VSYNC_GPIO_NUM 41
|
|
#define HREF_GPIO_NUM 38
|
|
#define PCLK_GPIO_NUM 37
|
|
|
|
|
|
const char* ssid = "RT-WiFi-1712";
|
|
const char* password = "yt3xihY2Ci";
|
|
|
|
const char* serverIP = "192.168.0.11";
|
|
const int serverPort = 9999;
|
|
const int localPort = 8888;
|
|
|
|
// !!! УНИКАЛЬНЫЙ ID ДЛЯ КАЖДОЙ ПЛАТЫ (например, 1 для первой, 2 для второй и т.д.)
|
|
const uint8_t DEVICE_ID = 1;
|
|
|
|
WiFiUDP udpVideo;
|
|
WiFiUDP udpCmd;
|
|
camera_config_t config;
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
// Настройка камеры (QVGA для стабильности)
|
|
config.ledc_channel = LEDC_CHANNEL_0;
|
|
config.ledc_timer = LEDC_TIMER_0;
|
|
config.pin_d0 = Y2_GPIO_NUM;
|
|
config.pin_d1 = Y3_GPIO_NUM;
|
|
config.pin_d2 = Y4_GPIO_NUM;
|
|
config.pin_d3 = Y5_GPIO_NUM;
|
|
config.pin_d4 = Y6_GPIO_NUM;
|
|
config.pin_d5 = Y7_GPIO_NUM;
|
|
config.pin_d6 = Y8_GPIO_NUM;
|
|
config.pin_d7 = Y9_GPIO_NUM;
|
|
config.pin_xclk = XCLK_GPIO_NUM;
|
|
config.pin_pclk = PCLK_GPIO_NUM;
|
|
config.pin_vsync = VSYNC_GPIO_NUM;
|
|
config.pin_href = HREF_GPIO_NUM;
|
|
config.pin_sscb_sda = SIOD_GPIO_NUM;
|
|
config.pin_sscb_scl = SIOC_GPIO_NUM;
|
|
config.pin_pwdn = PWDN_GPIO_NUM;
|
|
config.pin_reset = RESET_GPIO_NUM;
|
|
config.xclk_freq_hz = 20000000;
|
|
config.frame_size = FRAMESIZE_QVGA;
|
|
config.pixel_format = PIXFORMAT_JPEG;
|
|
config.grab_mode = CAMERA_GRAB_WHEN_EMPTY;
|
|
config.fb_count = 2;
|
|
|
|
esp_camera_init(&config);
|
|
|
|
// Подключение к Wi-Fi
|
|
WiFi.begin(ssid, password);
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(500);
|
|
}
|
|
Serial.println("Wi-Fi подключен!");
|
|
|
|
// Запуск прослушивания порта для команд
|
|
udpCmd.begin(localPort);
|
|
Serial.print("Ожидание команд на порту: ");
|
|
Serial.println(localPort);
|
|
}
|
|
|
|
void checkIncomingCommands() {
|
|
int packetSize = udpCmd.parsePacket();
|
|
if (packetSize > 0) {
|
|
char packetBuffer[255];
|
|
int len = udpCmd.read(packetBuffer, 255);
|
|
if (len > 0) { packetBuffer[len] = 0; }
|
|
|
|
String command = String(packetBuffer);
|
|
command.trim();
|
|
|
|
Serial.print("Получена команда: ");
|
|
Serial.println(command);
|
|
|
|
Serial.print("Получена команда: ");
|
|
Serial.println(command);
|
|
|
|
// Логика управления
|
|
if (command == "left") {
|
|
// Ваш код поворота налево
|
|
} else if (command == "right") {
|
|
// Ваш код поворота направо
|
|
} else if (command == "start") {
|
|
// Ваш код запуска моторов / логики
|
|
} else if (command == "stop") {
|
|
// Ваш код остановки
|
|
}
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
checkIncomingCommands();
|
|
|
|
camera_fb_t * fb = esp_camera_fb_get();
|
|
if (!fb) return;
|
|
|
|
size_t bufferSize = fb->len;
|
|
uint8_t * buf = fb->buf;
|
|
|
|
// Размер куска данных уменьшаем до 1023, чтобы вместе с 1 байтом ID пакет был 1024 байта
|
|
size_t chunkSize = 1023;
|
|
uint8_t packetBuffer[1024];
|
|
|
|
for (size_t i = 0; i < bufferSize; i += chunkSize) {
|
|
size_t sendSize = chunkSize;
|
|
if (i + chunkSize > bufferSize) {
|
|
sendSize = bufferSize - i;
|
|
}
|
|
|
|
// Формируем пакет: первый байт — ID, дальше — видеоданные
|
|
packetBuffer[0] = DEVICE_ID;
|
|
memcpy(packetBuffer + 1, buf + i, sendSize);
|
|
|
|
udpVideo.beginPacket(serverIP, serverPort);
|
|
udpVideo.write(packetBuffer, sendSize + 1); // Отправляем данные вместе с ID
|
|
udpVideo.endPacket();
|
|
}
|
|
|
|
esp_camera_fb_return(fb);
|
|
delay(10);
|
|
}
|