#include <FastLED.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include "WiFi.h"
#include <HTTPClient.h>
#include "time.h"
#define SPEAKER_PIN 8 // Пин для пищалки
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 19800;
const int daylightOffset_sec = 0;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
String GOOGLE_SCRIPT_ID = "AKfycbyJh1dYn5ceRP21Tf-OZ4m3M_JcVCoREetJnY2wvmNg5IT01l6pVFN5KH8aCo7TvBADDw";
Adafruit_MPU6050 mpu;
#define LED_PIN 15
#define NUM_LEDS 20
#define BRIGHTNESS 128
CRGB leds[NUM_LEDS];
#define LEFT_ECHO_PIN 12
#define LEFT_TRIG_PIN 14
#define RIGHT_ECHO_PIN 33
#define RIGHT_TRIG_PIN 32
#define FRONT_ECHO_PIN 26
#define FRONT_TRIG_PIN 25
#define BACK_ECHO_PIN 35
#define BACK_TRIG_PIN 4
bool wasRedLeft = false;
bool wasRedRight = false;
bool wasRedFront = false;
bool wasRedBack = false;
bool wasCollision = false;
// Переменные для поочередного писка
unsigned long lastBeepTime = 0;
bool isBeeping = false;
void setup(void){
Serial.begin(115200);
pinMode(SPEAKER_PIN, OUTPUT);
if (!mpu.begin()) {
Serial.println("Failed to find MPU6050 chip");
while (1) {
delay(10);
}
}
pinMode(LEFT_TRIG_PIN, OUTPUT);
pinMode(LEFT_ECHO_PIN, INPUT);
pinMode(RIGHT_TRIG_PIN, OUTPUT);
pinMode(RIGHT_ECHO_PIN, INPUT);
pinMode(FRONT_TRIG_PIN, OUTPUT);
pinMode(FRONT_ECHO_PIN, INPUT);
pinMode(BACK_TRIG_PIN, OUTPUT);
pinMode(BACK_ECHO_PIN, INPUT);
FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setBrightness(BRIGHTNESS);
// Подключение к WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" WiFi connected!");
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}
sensors_event_t event;
float readDistanceCMLEFT() {
digitalWrite(LEFT_TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(LEFT_TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(LEFT_TRIG_PIN, LOW);
int duration = pulseIn(LEFT_ECHO_PIN, HIGH);
return duration * 0.034 / 2;
}
float readDistanceCMRIGHT() {
digitalWrite(RIGHT_TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(RIGHT_TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(RIGHT_TRIG_PIN, LOW);
int duration = pulseIn(RIGHT_ECHO_PIN, HIGH);
return duration * 0.034 / 2;
}
float readDistanceCMFRONT() {
digitalWrite(FRONT_TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(FRONT_TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(FRONT_TRIG_PIN, LOW);
int duration = pulseIn(FRONT_ECHO_PIN, HIGH);
return duration * 0.034 / 2;
}
float readDistanceCMBACK() {
digitalWrite(BACK_TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(BACK_TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(BACK_TRIG_PIN, LOW);
int duration = pulseIn(BACK_ECHO_PIN, HIGH);
return duration * 0.034 / 2;
}
void clearRange(int start, int end) {
for(int i = start; i <= end; i++) {
leds[i] = CRGB::Black;
}
FastLED.show();
}
void lightRange(int start, int end, CRGB color) {
for(int i = start; i <= end; i++) {
leds[i] = color;
}
FastLED.show();
}
// Функция для поочередного писка (прерывистый звук)
void playBeep() {
tone(SPEAKER_PIN, 262, 250); // Частота 262 Гц, длительность 250 мс
}
// Функция для монотонного писка (непрерывный звук)
void playContinuousBeep() {
tone(SPEAKER_PIN, 262); // Без указания длительности - играет постоянно
}
// Функция отправки события в Google Таблицу
void sendEventToSheets(String eventType) {
if (WiFi.status() == WL_CONNECTED) {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
char timeStringBuff[50];
strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%d %H:%M:%S", &timeinfo);
String dateTime = String(timeStringBuff);
String encodedEvent = eventType;
encodedEvent.replace(" ", "%20");
String urlFinal = "https://script.google.com/macros/s/" + GOOGLE_SCRIPT_ID + "/exec?date=" + dateTime + "&avaria=" + encodedEvent;
Serial.print("Отправка события: ");
Serial.print(eventType);
Serial.print(" в ");
Serial.println(dateTime);
HTTPClient http;
http.begin(urlFinal.c_str());
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
int httpCode = http.GET();
if (httpCode > 0) {
Serial.print("HTTP Status Code: ");
Serial.println(httpCode);
String payload = http.getString();
Serial.println("Response: " + payload);
} else {
Serial.print("Ошибка HTTP: ");
Serial.println(httpCode);
}
http.end();
} else {
Serial.println("WiFi не подключен, событие не отправлено");
}
}
void loop(void){
float LEFTdistance = readDistanceCMLEFT();
float RIGHTdistance = readDistanceCMRIGHT();
float FRONTdistance = readDistanceCMFRONT();
float BACKdistance = readDistanceCMBACK();
mpu.getAccelerometerSensor()->getEvent(&event);
Serial.print("[");
Serial.print(millis());
Serial.print("] Z: ");
int z = event.acceleration.z;
Serial.println(z);
if(z <= 5){
// СТОЛКНОВЕНИЕ - МОНОТОННЫЙ ПИСК (непрерывный)
if(!wasCollision) {
sendEventToSheets("stolknowenie");
wasCollision = true;
playContinuousBeep(); // Включаем непрерывный писк
}
// Мигание красным
static unsigned long lastBlink = 0;
static bool ledState = false;
unsigned long currentMillis = millis();
if(currentMillis - lastBlink >= 500) {
lastBlink = currentMillis;
ledState = !ledState;
if(ledState) {
lightRange(0, 19, CRGB::Red);
} else {
clearRange(0, 19);
}
}
// Сбрасываем флаги сближения при столкновении
wasRedLeft = false;
wasRedRight = false;
wasRedFront = false;
wasRedBack = false;
} else {
// Сброс флага столкновения и выключение монотонного писка
if(wasCollision) {
wasCollision = false;
noTone(SPEAKER_PIN); // Выключаем пищалку
}
// ПЕРЕДНИЙ датчик
if(FRONTdistance <= 10){
lightRange(18, 19, CRGB::Red);
lightRange(0, 2, CRGB::Red);
if(!wasRedFront) {
sendEventToSheets("sblijenie speredi");
wasRedFront = true;
playBeep(); // Одиночный писк при срабатывании
}
} else {
wasRedFront = false;
if (FRONTdistance > 10 && FRONTdistance <= 50){
lightRange(18, 19, CRGB(255, 255, 0));
lightRange(0, 2, CRGB(255, 255, 0));
} else{
lightRange(18, 19, CRGB(0, 255, 100));
lightRange(0, 2, CRGB(0, 255, 100));
}
}
// ЗАДНИЙ датчик
if(BACKdistance <= 10){
lightRange(8, 12, CRGB::Red);
if(!wasRedBack) {
sendEventToSheets("sblijenie szadi");
wasRedBack = true;
playBeep(); // Одиночный писк при срабатывании
}
} else {
wasRedBack = false;
if(BACKdistance > 10 && BACKdistance <= 50) {
lightRange(8, 12, CRGB(255, 255, 0));
} else{
lightRange(8, 12, CRGB(0, 255, 100));
}
}
// ЛЕВЫЙ датчик
if(LEFTdistance <= 10){
lightRange(13, 17, CRGB::Red);
if(!wasRedLeft) {
sendEventToSheets("sblijenie sleva");
wasRedLeft = true;
playBeep(); // Одиночный писк при срабатывании
}
} else {
wasRedLeft = false;
if(LEFTdistance > 10 && LEFTdistance <= 50) {
lightRange(13, 17, CRGB(255, 255, 0));
} else{
lightRange(13, 17, CRGB(0, 255, 100));
}
}
// ПРАВЫЙ датчик
if(RIGHTdistance <= 10){
lightRange(3, 7, CRGB::Red);
if(!wasRedRight) {
sendEventToSheets("sblijenie sprava");
wasRedRight = true;
playBeep(); // Одиночный писк при срабатывании
}
} else {
wasRedRight = false;
if(RIGHTdistance > 10 && RIGHTdistance <= 50) {
lightRange(3, 7, CRGB(255, 255, 0));
} else{
lightRange(3, 7, CRGB(0, 255, 100));
}
}
}
delay(100);
}