From e3f5590f2df5669b33899c733c3cb5368e1ebf43 Mon Sep 17 00:00:00 2001 From: kkira Date: Sat, 16 May 2026 18:55:58 +0300 Subject: [PATCH] =?UTF-8?q?=D0=90=D0=B2=D1=82=D0=BE=D0=BD=D0=BE=D0=BC?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20ESP?= =?UTF-8?q?32?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- autonomy_esp/sketch_may14a.ino | 361 +++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 autonomy_esp/sketch_may14a.ino diff --git a/autonomy_esp/sketch_may14a.ino b/autonomy_esp/sketch_may14a.ino new file mode 100644 index 0000000..faf3039 --- /dev/null +++ b/autonomy_esp/sketch_may14a.ino @@ -0,0 +1,361 @@ +#include "esp_camera.h" +#include +#include "esp_http_server.h" +#include +#include +#include +#include +#include +#include + +// WIFI +const char* ssid = "Cathouse"; +const char* password = "88888888"; + +// CAMERA PINS +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 + +#define XCLK_GPIO_NUM 15 +#define SIOD_GPIO_NUM 4 +#define SIOC_GPIO_NUM 5 + +#define Y9_GPIO_NUM 16 +#define Y8_GPIO_NUM 17 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 12 +#define Y5_GPIO_NUM 10 +#define Y4_GPIO_NUM 8 +#define Y3_GPIO_NUM 9 +#define Y2_GPIO_NUM 11 + +#define VSYNC_GPIO_NUM 6 +#define HREF_GPIO_NUM 7 +#define PCLK_GPIO_NUM 13 + +// OLED +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); + +// SENSOR +BH1750 lightMeter; + +// LED +#define LED_PIN 21 +#define LED_COUNT 8 +Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); + +// AHT20 +#define AHT20_ADDR 0x38 +float temperature = 0; +float humidity = 0; + +// SERVO +#define SERVO_PIN 47 +Servo myServo; +bool isMoving = false; +bool isNight = false; +unsigned long moveStart = 0; +int servoDirection = 90; + + +// STREAM +static esp_err_t stream_handler(httpd_req_t *req) { + + camera_fb_t * fb = NULL; + + static const char* boundary = + "\r\n--frame\r\n"; + + static const char* type = + "multipart/x-mixed-replace;boundary=frame"; + + static const char* header = + "Content-Type: image/jpeg\r\n" + "Content-Length: %u\r\n\r\n"; + + httpd_resp_set_type(req, type); + + while (true) { + fb = esp_camera_fb_get(); + if (!fb) continue; + + httpd_resp_send_chunk(req, boundary, strlen(boundary)); + + char buf[64]; + int hlen = snprintf(buf, sizeof(buf), header, fb->len); + + httpd_resp_send_chunk(req, buf, hlen); + httpd_resp_send_chunk(req, (const char*)fb->buf, fb->len); + esp_camera_fb_return(fb); + delay(120); + } + return ESP_OK; +} + +// SERVER +httpd_handle_t server = NULL; + + +void startServer() { + httpd_config_t config = + HTTPD_DEFAULT_CONFIG(); + + config.server_port = 80; + httpd_start(&server, &config); + + httpd_uri_t uri = { + .uri = "/stream", + .method = HTTP_GET, + .handler = stream_handler, + .user_ctx = NULL + }; + httpd_register_uri_handler(server, &uri); +} + + +// CAMERA +void initCamera() { + + camera_config_t config; + + 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_sccb_sda = SIOD_GPIO_NUM; + config.pin_sccb_scl = SIOC_GPIO_NUM; + + config.pin_pwdn = PWDN_GPIO_NUM; + config.pin_reset = RESET_GPIO_NUM; + + config.pixel_format = PIXFORMAT_JPEG; + config.xclk_freq_hz = 20000000; + config.frame_size = FRAMESIZE_QVGA; + config.jpeg_quality = 18; + config.fb_count = 1; + + if (esp_camera_init(&config) != ESP_OK) { + Serial.println("Camera FAIL"); + while (true); + } + + sensor_t * s = esp_camera_sensor_get(); + + s->set_vflip(s, 1); + s->set_brightness(s, 1); + s->set_whitebal(s, 1); + s->set_awb_gain(s, 1); + s->set_exposure_ctrl(s, 1); + s->set_gain_ctrl(s, 1); +} + + +// AHT20 +bool readAHT20(float &temp, float &hum) { + uint8_t cmd[3] = {0xAC, 0x33, 0x00}; + Wire.beginTransmission(AHT20_ADDR); + Wire.write(cmd, 3); + + if (Wire.endTransmission() != 0) + return false; + + delay(80); + Wire.requestFrom(AHT20_ADDR, 6); + + if (Wire.available() < 6) + return false; + + uint8_t data[6]; + + for (int i = 0; i < 6; i++) { + data[i] = Wire.read(); + } + uint32_t h = + ((data[1] << 12) | + (data[2] << 4) | + (data[3] >> 4)); + + uint32_t t = + ((data[3] & 0x0F) << 16) | + (data[4] << 8) | + data[5]; + + hum = (h * 100.0) / 1048576.0; + temp = + (t * 200.0 / 1048576.0) - 50; + return true; +} + + +// SETUP +void setup() { + Serial.begin(115200); + delay(2000); + + // CAMERA + initCamera(); + + // WIFI + WiFi.begin(ssid, password); + WiFi.setSleep(false); + while (WiFi.status() != WL_CONNECTED) { + delay(300); + Serial.print("."); + } + Serial.println("\nWiFi OK"); + Serial.println(WiFi.localIP()); + + // I2C + Wire.begin(1, 2); + Wire.setClock(100000); + + // BH1750 + lightMeter.begin(); + + // OLED + if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { + Serial.println("OLED FAIL"); + while (true); + } + + display.clearDisplay(); + display.setTextSize(1); + display.setTextColor(SSD1306_WHITE); + + // SERVER + startServer(); + + // SERVO + myServo.attach(SERVO_PIN); + myServo.write(92); // стоп + delay(1000); + myServo.detach(); + + Serial.println("SERVO READY"); + + strip.begin(); + strip.show(); + strip.setBrightness(80); + + Serial.println("OPEN /stream"); +} + + +void setStripColor(uint8_t r, uint8_t g, uint8_t b) { + for (int i = 0; i < LED_COUNT; i++) { + strip.setPixelColor(i, strip.Color(r, g, b)); + } + strip.show(); +} + + +// LOOP +unsigned long last = 0; + + +void loop() { + + static float lux = 0; + + // UPDATE + if (millis() - last > 2000) { + + last = millis(); + + lux = lightMeter.readLightLevel(); + + readAHT20(temperature, humidity); + + Serial.println("----"); + + Serial.print("Lux: "); + Serial.println(lux); + + Serial.print("Temp: "); + Serial.println(temperature); + + Serial.print("Hum: "); + Serial.println(humidity); + + display.clearDisplay(); + + display.setCursor(0, 0); + + display.print("Light: "); + display.print(lux); + display.println(" lx"); + + display.print("Temp: "); + display.print(temperature); + display.println(" C"); + + display.print("Hum: "); + display.print(humidity); + display.println(" %"); + + display.println(); + + display.print("MODE: "); + + display.println( + isNight ? "NIGHT" : "DAY" + ); + + display.display(); + } + + // NIGHT + if (lux < 200 && !isNight) { + isNight = true; + isMoving = true; + moveStart = millis(); + servoDirection = 30; + } + + // DAY + if (lux >= 200 && isNight) { + isNight = false; + isMoving = true; + moveStart = millis(); + servoDirection = 150; + } + + // MOVE + if (isMoving) { + myServo.attach(SERVO_PIN); + if (millis() - moveStart < 5000) { + myServo.write(servoDirection); + } else { + myServo.write(92); // стоп + delay(200); + myServo.detach(); + isMoving = false; + } + } + + // WS2812 + if (isNight) { + // НОЧЬ + setStripColor(0, 0, 40); + } else { + // ДЕНЬ + setStripColor(40, 25, 10); + } + + delay(30); +} \ No newline at end of file