это уже для меня сложнее, без помощи не разберусь . Спасибо!
пока первый вариант пытаюсь
это уже для меня сложнее, без помощи не разберусь . Спасибо!
пока первый вариант пытаюсь
const int led1 = 2; const int led2 = 3; const int led3 = 4; // Время для каждого LED (мс) unsigned long duration1 = 5000; // LED1 unsigned long duration2 = 10000; // LED2 unsigned long duration3 = 15000; // LED3 unsigned long startTime = 0; unsigned long currentDuration = 0; int stage = 0; // 0=стоп, 1=LED1, 2=LED2, 3=LED3 bool running = false; // цикл стартует только после команды START void setup() { Serial.begin(9600); pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); Serial.println("Система готова"); } void loop() { // Проверка команд с телефона if (Serial.available()) { String cmd = Serial.readStringUntil('\n'); cmd.trim(); if (cmd == "S" && !running) { stage = 1; running = true; activateStage(); Serial.println("СТАРТ"); } if (cmd == "X") stopAll(); // Изменение времени только при необходимости if (cmd.startsWith("T1")) duration1 = cmd.substring(2).toInt() * 1000UL; if (cmd.startsWith("T2")) duration2 = cmd.substring(2).toInt() * 1000UL; if (cmd.startsWith("T3")) duration3 = cmd.substring(2).toInt() * 1000UL; } // Переход к следующему этапу if (running && millis() - startTime >= currentDuration) { nextStage(); } } void activateStage() { digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); if (stage == 1) currentDuration = duration1; if (stage == 2) currentDuration = duration2; if (stage == 3) currentDuration = duration3; if (stage == 1) digitalWrite(led1, HIGH); if (stage == 2) digitalWrite(led2, HIGH); if (stage == 3) digitalWrite(led3, HIGH); startTime = millis(); Serial.print("LED "); Serial.print(stage); Serial.println(" включен"); } void nextStage() { stage++; if (stage > 3) { Serial.println("Цикл завершен"); stopAll(); return; } activateStage(); } void stopAll() { digitalWrite(led1, LOW); digitalWrite(led2, LOW); digitalWrite(led3, LOW); running = false; stage = 0; Serial.println("СТОП"); }
Итак делюсь проделанной работой благодаря чат GPT (какое удовольствие работать )
Значит сейчас у меня работает:
HC-06 через пины 0/1
Кнопка START
Кнопка STOP
Автоматический цикл 1 → 2 → 3
Таймеры
При отправлении S в приложении запускается автоматический цикл
в приложении приходит состоянии Лед1 Лед2 Лед три пишет таймер 123 и пишет когда закончен цикл.
Спасибо огромное Pyotr, MMM, BABOS!!! Без вас я бы не дотумкался
Теперь сделал еще
Выбор времени с телефона
S
START, запускает цикл LED1→LED2→LED3
X
STOP, останавливает цикл
T1+число
Изменяет время LED1 (сек)
T2+число
Изменяет время LED2 (сек)
T3+число
Изменяет время LED3 (сек)
Serial.println("LED3 включен");
это что вам все таки надо было просто в монитор порта вывести ? или это пульт ваш понимает и включает нужную лампочку ?
что бы вам помочь, нужен пример кода, что бы понять как вы управляете лампочкой, и это отображается в пульте…
так что я вам совсем не помог, и самоустранился от помощи))) по причине отсутствия от вас кода…
Ну почитай тогда:
![]()
//================ФИНАЛЬНЫЙ СКЕТ РАЗДВИЖНЫХ ИЛИ ОТКАТНЫХ ВОРОТ ОДИН УЛЬРАЗВУКОВОЙ ДАТЧИК РАССТОЯНИЯ И ДВА ФОТОДАТЧИКА================
#include <Arduino.h>
// ===== PINS =====
#define STEP_PIN 3
#define DIR_PIN 2
#define TRIG_PIN 8
#define ECHO_PIN 9
#define PHOTO1_PIN 12
#define PHOTO2_PIN 13
// LM339 open collector: usually LOW = active
const int PHOTO_ACTIVE_LEVEL = LOW;
// ===== PARAMETERS (BT commands) =====
int NEAR_CM = 40;
int FAR_CM = 50;
const int STEPS_PER_REV = 200; // поменяй на 400, если микрошаг = 400 шаг/об
long doorSteps = 1200; // Nxxxx or Rn*STEPS_PER_REV
unsigned int PULSE_US = 10; // для TB6600 достаточно 5..10 us
unsigned int SPEED_US = 1200; // Sxxxx (200..3000), больше = медленнее
unsigned long closeDelayMs = 2000; // Dxxxx (200..60000)
unsigned long reopenHoldMs = 2000; // Hxxxx (0..10000)
unsigned long reopenHoldStart = 0;
bool forceOpenToZero = false;
// ===== TELEMETRY =====
const unsigned long SEND_INTERVAL_MS = 1000;
unsigned long lastSendMs = 0;
const unsigned long SENSOR_PERIOD_MS = 120;
unsigned long lastSensorMs = 0;
// ===== SENSOR VALUES =====
long lastCm = -1;
// --- ultrasonic confirm ---
const int US_CONFIRM = 5;
int nearCnt = 0, farCnt = 0;
bool nearOk = false, farOk = false;
const unsigned long REVERSE_HOLD_MS = 500;
unsigned long nearOkSinceMs = 0;
// --- photo confirm ---
const int PHOTO_CONFIRM = 3;
int photoCnt1 = 0, photoCnt2 = 0;
bool photoOk1 = false, photoOk2 = false;
// ===== MOTION / POSITION =====
enum Motion { IDLE, OPENING, CLOSING };
Motion motion = IDLE;
// posSteps: 0 = open, doorSteps = closed
long posSteps = 0;
// Close timer
bool closeTimerActive = false;
unsigned long closeTimerStart = 0;
// Step generator (non-blocking)
unsigned long lastStepUs = 0;
bool stepHigh = false;
unsigned long stepHighSinceUs = 0;
// ---------- HC-SR04 ----------
long readCmOnce() {
digitalWrite(TRIG_PIN, LOW); delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH); delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
unsigned long d = pulseIn(ECHO_PIN, HIGH, 25000UL);
if (d == 0) return -1;
return (long)(d / 58);
}
long readCmFiltered() {
long sum = 0; int cnt = 0;
for (int i = 0; i < 3; i++) {
long cm = readCmOnce();
if (cm > 0) { sum += cm; cnt++; }
delay(8);
}
if (cnt == 0) return -1;
return sum / cnt;
}
// ---------- STEPPER ----------
void setDirForMotion(Motion m) {
// если направление перепутано — поменяй HIGH/LOW местами
if (m == OPENING) digitalWrite(DIR_PIN, HIGH);
if (m == CLOSING) digitalWrite(DIR_PIN, LOW);
delayMicroseconds(50);
}
void startOpening() {
if (posSteps <= 0) { motion = IDLE; posSteps = 0; return; }
motion = OPENING;
setDirForMotion(OPENING);
}
void startClosing() {
if (posSteps >= doorSteps) { motion = IDLE; posSteps = doorSteps; return; }
motion = CLOSING;
setDirForMotion(CLOSING);
}
void stopMotion() { motion = IDLE; }
void updateStepper() {
if (motion == IDLE) return;
// reached fully open
if (motion == OPENING && posSteps <= 0) {
posSteps = 0;
stopMotion();
if (forceOpenToZero) reopenHoldStart = millis();
forceOpenToZero = false;
return;
}
// reached fully closed
if (motion == CLOSING && posSteps >= doorSteps) {
posSteps = doorSteps;
stopMotion();
return;
}
unsigned long now = micros();
if (stepHigh) {
if (now - stepHighSinceUs >= PULSE_US) {
digitalWrite(STEP_PIN, LOW);
stepHigh = false;
if (motion == OPENING) posSteps--;
else if (motion == CLOSING) posSteps++;
}
return;
}
if (now - lastStepUs >= SPEED_US) {
digitalWrite(STEP_PIN, HIGH);
stepHigh = true;
stepHighSinceUs = now;
lastStepUs = now;
}
}
// ---------- CONFIRM HELPERS ----------
static inline void updateUltrasonicConfirm(long cm) {
if (cm < 0) {
nearCnt = farCnt = 0;
nearOk = farOk = false;
nearOkSinceMs = 0;
return;
}
if (cm < NEAR_CM) {
nearCnt++;
farCnt = 0;
} else if (cm > FAR_CM) {
farCnt++;
nearCnt = 0;
} else {
nearCnt = 0;
farCnt = 0;
}
bool prevNearOk = nearOk;
nearOk = (nearCnt >= US_CONFIRM);
farOk = (farCnt >= US_CONFIRM);
unsigned long ms = millis();
if (nearOk && !prevNearOk) nearOkSinceMs = ms;
if (!nearOk) nearOkSinceMs = 0;
}
static inline void updatePhotoConfirm(bool raw1, bool raw2) {
if (raw1) photoCnt1++; else photoCnt1 = 0;
if (raw2) photoCnt2++; else photoCnt2 = 0;
photoOk1 = (photoCnt1 >= PHOTO_CONFIRM);
photoOk2 = (photoCnt2 >= PHOTO_CONFIRM);
}
// ---------- STATUS / COMMANDS ----------
void printStatus() {
Serial.print("STAT;DelayMs="); Serial.print(closeDelayMs);
Serial.print(";DoorSteps="); Serial.print(doorSteps);
Serial.print(";HoldMs="); Serial.print(reopenHoldMs);
Serial.print(";Near="); Serial.print(NEAR_CM);
Serial.print(";Far="); Serial.print(FAR_CM);
Serial.print(";SpeedUs="); Serial.print(SPEED_US);
Serial.print(";cm="); Serial.print(lastCm);
Serial.print(";nearOk="); Serial.print(nearOk ? 1 : 0);
Serial.print(";farOk="); Serial.print(farOk ? 1 : 0);
Serial.print(";B1="); Serial.print(photoOk1 ? 1 : 0);
Serial.print(";B2="); Serial.print(photoOk2 ? 1 : 0);
Serial.print(";pos="); Serial.print(posSteps);
Serial.print(";motion="); Serial.println((int)motion);
}
void handleSerial() {
static char buf[40];
static byte idx = 0;
while (Serial.available()) {
char c = Serial.read();
if (c == '\n' || c == '\r') {
if (idx == 0) continue;
buf[idx] = '\0';
idx = 0;
if (!strcmp(buf, "STAT")) { printStatus(); return; }
if (buf[0] == 'D') {
long v = atol(buf + 1);
if (v < 200) v = 200;
if (v > 60000) v = 60000;
closeDelayMs = (unsigned long)v;
Serial.print("OK;DelayMs="); Serial.println(closeDelayMs);
return;
}
if (buf[0] == 'N') {
long v = atol(buf + 1);
if (v < 10) v = 10;
if (v > 50000) v = 50000;
doorSteps = v;
if (posSteps > doorSteps) posSteps = doorSteps;
Serial.print("OK;DoorSteps="); Serial.println(doorSteps);
return;
}
if (buf[0] == 'R') {
long rev = atol(buf + 1);
if (rev < 1) rev = 1;
if (rev > 200) rev = 200;
doorSteps = rev * (long)STEPS_PER_REV;
if (posSteps > doorSteps) posSteps = doorSteps;
Serial.print("OK;DoorSteps="); Serial.println(doorSteps);
return;
}
if (buf[0] == 'H') {
long v = atol(buf + 1);
if (v < 0) v = 0;
if (v > 10000) v = 10000;
reopenHoldMs = (unsigned long)v;
Serial.print("OK;HoldMs="); Serial.println(reopenHoldMs);
return;
}
if (buf[0] == 'S') {
long v = atol(buf + 1);
if (v < 200) v = 200;
if (v > 3000) v = 3000;
SPEED_US = (unsigned int)v;
Serial.print("OK;SpeedUs="); Serial.println(SPEED_US);
return;
}
if (!strncmp(buf, "NEAR", 4)) {
int v = atoi(buf + 4);
if (v < 10) v = 10;
if (v > 200) v = 200;
NEAR_CM = v;
Serial.print("OK;Near="); Serial.println(NEAR_CM);
return;
}
if (!strncmp(buf, "FAR", 3)) {
int v = atoi(buf + 3);
if (v < NEAR_CM + 5) v = NEAR_CM + 5;
if (v > 300) v = 300;
FAR_CM = v;
Serial.print("OK;Far="); Serial.println(FAR_CM);
return;
}
Serial.println("ERR;Use D2000 N1200 R6 H3000 S1200 NEAR40 FAR50 STAT");
} else {
if (idx < sizeof(buf) - 1) buf[idx++] = c;
}
}
}
// ---------- SETUP ----------
void setup() {
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
digitalWrite(STEP_PIN, LOW);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(PHOTO1_PIN, INPUT_PULLUP);
pinMode(PHOTO2_PIN, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("SYSTEM READY (1x US + 2x PHOTO) ENA=DISCONNECTED");
printStatus();
}
// ---------- LOOP ----------
void loop() {
handleSerial();
updateStepper();
unsigned long ms = millis();
if (ms - lastSensorMs >= SENSOR_PERIOD_MS) {
lastSensorMs = ms;
// read sensors
lastCm = readCmFiltered();
bool raw1 = (digitalRead(PHOTO1_PIN) == PHOTO_ACTIVE_LEVEL);
bool raw2 = (digitalRead(PHOTO2_PIN) == PHOTO_ACTIVE_LEVEL);
updateUltrasonicConfirm(lastCm);
updatePhotoConfirm(raw1, raw2);
bool anyPhoto = (photoOk1 || photoOk2);
// telemetry
if (ms - lastSendMs >= SEND_INTERVAL_MS) {
lastSendMs = ms;
Serial.print("*D"); Serial.println(lastCm);
Serial.print("*B1"); Serial.println(photoOk1 ? 1 : 0);
Serial.print("*B2"); Serial.println(photoOk2 ? 1 : 0);
}
// --- PHOTO SAFETY: force open to zero and block closing ---
if (anyPhoto) {
closeTimerActive = false;
if (motion == CLOSING || (motion == IDLE && posSteps > 0)) {
forceOpenToZero = true;
startOpening();
}
return; // пока фото активно — не закрываем
}
// --- US SAFETY: if closing and nearOk stable -> force open to zero ---
if (motion == CLOSING && nearOk) {
if (nearOkSinceMs != 0 && (ms - nearOkSinceMs >= REVERSE_HOLD_MS)) {
closeTimerActive = false;
forceOpenToZero = true;
startOpening();
}
return;
}
// block closing while forced opening not finished
if (forceOpenToZero) return;
// hold after emergency open
if (reopenHoldStart != 0) {
if (ms - reopenHoldStart < reopenHoldMs) return;
reopenHoldStart = 0;
}
// --- normal logic ---
if (nearOk) {
closeTimerActive = false;
if (motion == IDLE && posSteps > 0) startOpening();
return;
}
if (farOk) {
if (posSteps < doorSteps && motion == IDLE) {
if (!closeTimerActive) {
closeTimerActive = true;
closeTimerStart = ms;
} else if (ms - closeTimerStart >= closeDelayMs) {
closeTimerActive = false;
startClosing();
}
}
}
}
}
ОСНОВНЫЕ КОМАНДЫ ДЛЯ ПРИЛОЖЕНИЯ Serial Bluetooth Terminal
(в приложении Bluetooth Electroniks корректно не отправляет символы ответ от Ардуино не приходит не добился)
STAT
STAT
Показывает текущее состояние:
расстояние с обоих датчиков
near/far статус
состояние фотодатчиков
позицию двери (pos)
режим движения (motion)
текущие параметры (скорость, задержки и т.д.)
Sxxxx — скорость двигателя
S1200
Меняет скорость движения (в микросекундах между шагами).
Чем больше число → тем медленнее движение.
Пример:
S700 — быстрее
S1200 — медленнее
S2000 — очень медленно
Диапазон: 200–3000
Dxxxx — задержка закрытия
D3000
Задержка перед закрытием после того, как стало “far”.
В миллисекундах.
D2000 = 2 секунды
D5000 = 5 секунд
Hxxxx — пауза после аварийного открытия
H3000
После аварийного открытия (ультразвук или фото) дверь ждёт это время перед возможным закрытием.
Nxxxx — количество шагов до полного закрытия
N1200
Устанавливает длину хода двери в шагах.
Используется если ты считаешь ход в шагах
Rxx — обороты двигателя
R6
Устанавливает длину хода в оборотах.
NEAR40
Если расстояние меньше этого значения — считается “человек рядом”.
8) FARxx — порог “далеко”
FAR55
Если расстояние больше этого значения — считается “никого нет”.
FAR должен быть больше NEAR минимум на 5 см.
Как логика работает сейчас
Любой ультразвук < NEAR → открытие
Оба ультразвука > FAR → закрытие
Любой фотобарьер активен → открытие до нуля
Во время закрытия срабатывание датчика → полный реверс
Я использовал фотобарьры микросхемой LM339
ультразвуковой датчики расстояния HC-SR04
драйвер для шагового двигателя ТВ6600
блютуз HC-06 на пины 0/1 (поэтому пишем только через Serial при загрузке блютуз отключаем с RX/TX если блютуз на других пинах 2/3 пишем через SoftwareSerial )
Про ENA- (Enable в драйвере а именно минус я закоротил вместе с DIR - PUL-и на минус в Ардуино а плюс ENA никуда не подлючал)
Концевики пока не подключал пока испытываю какие есть и будут ощибки