Короткий простой код управления кареткой

код вот этот, другие (полее поздние и более “правильные” модификации я не пробовал, попробую позже, при наличии свободного времени)

void setup() {
  pinMode(10, INPUT);
  pinMode(9, INPUT);
  pinMode(20, OUTPUT);
  pinMode(22, OUTPUT);
  if (digitalRead(10) == 0 && digitalRead(9) == 0 ) { // если каретка ни вверху и не внизу , то двигать вниз после паузы
    delay(1000); // пауза перед движением вниз
    digitalWrite(20, 1); // едем вниз
}
}

void loop() {


    if (digitalRead(10) == 1 && digitalRead(9) == 0) { // если есть лог 1 на выходе 10,  и лог 0 на выходе 9, то каретка вверху, надо её остановить. сделать паузу и начать двигать вниз
      digitalWrite(22, 0); // останавливаем движение каретки вверх
      delay(1 * 1000); // пауза перед спуском
      digitalWrite(20, 1); // начинаем движение каретки вниз
      delay(1 * 1000); 
    }
    if (digitalRead(10) == 0 && digitalRead(9) == 1) { // если ло 1 на выходе 9 и лог 0 на выходе 10, то каретка внизу, надо её остановить, сделать паузу, двигать вверх
        digitalWrite(20, 0); // останавливаем движение вниз
        delay(1 * 1000); // пауза в нижнем положении
        digitalWrite(22, 1); // начинаем движение вверх
        delay(1 * 1000); 
    }
}

Чёрт, а ведь вертелась какая-то мысль про эти выводы! Увидел эти 20 и 21, понял, что это наверное мега, и хотел ещё спросить - а правильно ли их там нашли? Но забыл! :slight_smile:
Ладно, разобрались и хорошо!

1 лайк

Добрый день, опять я.
Старый проект забросил, теперь снова надо.

Код такой

void setup() {
  pinMode(4, INPUT); //  вход от нижнего датчика
  pinMode(5, INPUT); // вход от верхнего датчика
  pinMode(6, OUTPUT); // лог 1 = движение вверх
  pinMode(7, OUTPUT); // лог 1 = движение вниз
  if (digitalRead(4) == 0 && digitalRead(5) == 0 ) { // если каретка не вверху и не внизу , то двигать вверх после паузы
    delay(500); // пауза перед движением вверх
    digitalWrite(6, 1); // едем в верх
}
}

void loop() {

    if (digitalRead(4) == 1 && digitalRead(5) == 0) { // если есть лог 1 на выходе 4,  и лог 0 на выходе 5, то каретка внизу, надо её остановить. сделать паузу и начать двигать вверх
      digitalWrite(7, 0); // останавливаем движение каретки вниз
            delay(10000); // пауза после остановки
      digitalWrite(6, 1); // начинаем движение каретки вверх
      
    }
    if (digitalRead(4) == 0 && digitalRead(5) == 1) { // если ло 1 на выходе 5 и лог 0 на выходе 4, то каретка вверху, надо её остановить, сделать паузу, двигать вниз
        digitalWrite(6, 0); // останавливаем движение каретки вверх
        delay(20000); // пауза после полной остановки
        digitalWrite(7, 1); // начинаем движение вверх
        
    }
}

проблема в паузах, строки delay (10000) и delay (20000) конкретно в том, что если время перемещения каретки между датчиками меньше этой паузы (т.е. проезжает за время, которое меньше выставленной паузы) то сигнал на остановку двигателя не приходит и каретка уезжает совсем. Получается, как будто система не реагирует на датчики.
на всех датчиках стоят подключенные светодиоды и это четко видно. Что делать, подскажите, пожалуйста.

Могут срабатывать второй раз после команды на смену движения digitalWrite(6, 1); digitalWrite(7, 1);. Т.к. датчик может не успеть выключится. И в этом случае появится лишний delay.
Как вариант решения, можно добавить в if поверку направления движения.

Датчик не выключается при нахождении каретки в крайних положениях, т.е. он “включился” и будет включен пока каретка не поедет в обратную сторону (не выйдет из магнитного поля магнита закрепленного на каретке). и даже некоторе время после того как поедет все равно не выключится (милимметров 7-8) от крайнего положения. особенность герконов в том, что для срабатывания надо более сильное магнитное поле, чем для отпускания, т.е. если включился, то дребезга нет в пограничном состоянии.

Проверьте соединения(к примеру код не соответствует рисунку), и , исправность элементов схемы. Так же источники питания. Надёжно ли срабатывают герконы и работает драйвер.

Исходя из логики кода - движение должно остановиться на подходе к датчику, и не возобновляться на время паузы.
Длительность паузы роли не играет.

Постараюсь завтра сделать короткое видео как это работает с пояснениями.
Логика, конечно, работы очевидная, но что-то работает не так. Скорее всего я где-то косячу, просто со временем мысли и глаз замыливается и я сам не вижу, сторонний взгляд может СИЛЬНО помоч, ткнув носом в “детскую” проблему. Спасибо за отклик(и), очень признателен.

Есть подозрение, что система не реагирует, потому что тупо виснет при старте мотора…

@Upper вам указал на явный косяк, но всё равно, остановка и первая пауза должны отрабатывать.
А у вас

Значит, где-то ещё ошибка

Пустое сообщение? А что, так можно?

1 лайк

так у него номер оказал 73 - наилучшие пожелания то бишь!

2 лайка

Хорошо что не 99.

Как оказалось - да! Ну, оно не совсем пустое…
Не понравилось, то что написал. Решил удалить. Вместо текста написал del. Выругалось на три символа. Заключил del в угловые скобки - а оно вона как! :slight_smile:
Оно внутри такое и сейчас

1 лайк

каюсь, я честно пытался посмотреть, что ты там разместил, увы )))

1 лайк

Получилось однако)))

Вот используемый код

void setup() {
  pinMode(4, INPUT); //  вход от верхнего датчика
  pinMode(5, INPUT); // вход от нижнего датчика
  pinMode(6, OUTPUT); // лог 1 = движение вверх
  pinMode(7, OUTPUT); // лог 1 = движение вниз
  if (digitalRead(4) == 0 && digitalRead(5) == 0 ) { // если каретка не вверху и не внизу , то двигать вверх после паузы
    delay(500); // пауза перед движением вверх
    digitalWrite(6, 1); // едем в верх
}
}

void loop() {

    if (digitalRead(4) == 1 && digitalRead(5) == 0) { // если есть лог 1 на выходе 4 и лог 0 на выходе 5, то каретка вверху, надо её остановить. сделать паузу и начать двигать вниз
      digitalWrite(6, 0); // останавливаем движение каретки вверх
            delay(1000); // пауза после остановки
      digitalWrite(7, 1); // начинаем движение каретки вниз
      
    }
    if (digitalRead(4) == 0 && digitalRead(5) == 1) { // если есть лог 0 на выходе 4 и лог 1 на выходе 5, то каретка внизу, надо её остановить, сделать паузу, двигать вверх
        digitalWrite(7, 0); // останавливаем движение каретки вниз
        delay(1000); // пауза после полной остановки
        digitalWrite(6, 1); // начинаем движение вверх
        
    }
}

если паузы выставлены 1000 мсек( 1сек) то всё работает, вот видео как оно работает
Извините, как вставить видео на форуме не знаю, по ссылке (40 мб) https://cloud.mail.ru/public/DC99/ADCfpaRda

А если паузы выставлены, к примеру, 10 000 (10 сек) то каретка не останавливается. (160 мб)
Код тот же, только в цикле loop delay (10000) https://cloud.mail.ru/public/ujAg/fWBBhyGUv

Это плохо, что так и не поняли, что вам выше сказали, и не смогли исправить.
Вообще, использовать delay() - неудачное решение, т.к. датчики остаются “без присмотра”
Вот, чисто из интереса, подправил чуть ваш код, но не проверял, т.к. не где, да и времени маловато.Возможно надо будет немного подправить.

Спойлер
#define DEBONCE_TIME 40
#define OUT_OF_RANGE_TIME   500 // подобрать
const uint8_t ALARM_PIN = 2; //Светодиод сигнализации аварии
bool Up = false;

void setup() {
  pinMode(4, INPUT); //  вход от нижнего датчика
  pinMode(5, INPUT); // вход от верхнего датчика
  pinMode(6, OUTPUT); // лог 1 = движение вверх
  pinMode(7, OUTPUT); // лог 1 = движение вниз
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  
  pinMode(ALARM_PIN, OUTPUT);
  digitalWrite(ALARM_PIN, LOW);
  
  if (digitalRead(4) == 0) { // если каретка не внизу , то двигать вверх после паузы
    delay(DEBONCE_TIME);
    if (digitalRead(4) == 0)
    {
    delay(500); // пауза перед движением вверх
    digitalWrite(6, 1); // едем в верх 6,1   7, 0 вверх
	Up = true;
	}
 }  
}

void Alarm()
{
  if(digitalRead(6))
  digitalWrite(7, 1);//останавливаем мотор
  else
  digitalWrite(7, 0);	
  digitalWrite(ALARM_PIN, HIGH);//зажигаем аварийный светодиод
}

void loop() {
      
    if (digitalRead(4) == 1 && !Up) { //ПРИЕХАЛИ - НИЗ! если есть лог 1 на выходе 4,  и лог 0 на выходе 5, то каретка внизу, надо её остановить. сделать паузу и начать двигать вверх
	  delay(DEBONCE_TIME);//задержка, для антидребезга
	 if (digitalRead(4) == 1 && !Up)//простейший антидребезг
	 {		 
      digitalWrite(7, 0); // останавливаем движение каретки вниз
      delay(10000); // пауза после остановки
      digitalWrite(6, 1); // начинаем движение каретки вверх
	  Up = true;  
	 }
    }
	
    if (digitalRead(5) == 1 && Up) { //ПРИЕХАЛИ - ВЕРХ! если ло 1 на выходе 5 и лог 0 на выходе 4, то каретка вверху, надо её остановить, сделать паузу, двигать вниз
	    delay(DEBONCE_TIME);//
	  if (digitalRead(5) == 1 && Up)//
	  {
        digitalWrite(6, 0); // останавливаем движение каретки вверх
        delay(20000); // пауза после полной остановки
        digitalWrite(7, 1); // начинаем движение ВНИЗ
        Up = false;
	  }
    }
	
	//
    if (digitalRead(4) == 1 && digitalRead(5) == 1)//Если некорректные значения
	{
	  delay(DEBONCE_TIME);
	 if (digitalRead(4) == 1 && digitalRead(5) == 1) 
     {
	  Alarm();                                    //Авария
	 }
	}
	
	if((digitalRead(5) == 1 && !Up) || (digitalRead(4) == 1 && Up))//Если некорректные значения
	{
	  delay(OUT_OF_RANGE_TIME); //(время уверенного отъезда от датчика)
	 if((digitalRead(5) == 1 && !Up) || (digitalRead(4) == 1 && Up))//после отъезда от датчика
	 {
	   Alarm();
	 }		 	
	}
	
		
}

P.S. Чуть подправил.

Вчера пообщался с ИИ и он мне подсказал тоже самое, мол, delay использовать в программе это сплошное вредительство и надо немножко помассировать лицо тому, кто его пихает новичкам. Используй, говорит, millis.

unsigned long previousTime = 0; // Переменная для отслеживания времени
int pauseAtTop = 20000; // Пауза в верхней точке (в миллисекундах)
int pauseAtBottom = 5000; // Пауза в нижней точке (в миллисекундах)
bool isMovingUp = false; // Флаг, указывающий движение вверх
bool isMovingDown = false; // Флаг, указывающий движение вниз

void setup() {
  pinMode(4, INPUT); // Вход от верхнего датчика
  pinMode(5, INPUT); // Вход от нижнего датчика
  pinMode(6, OUTPUT); // Лог 1 = движение вверх
  pinMode(7, OUTPUT); // Лог 1 = движение вниз

  if (digitalRead(4) == 0 && digitalRead(5) == 0) { 
    digitalWrite(6, 1); // Начинаем движение вверх
    isMovingUp = true; // Устанавливаем флаг движения вверх
  }
}

void loop() {
  int topSensor = digitalRead(4); // Состояние верхнего датчика
  int bottomSensor = digitalRead(5); // Состояние нижнего датчика

  // Если каретка достигла верхней точки
  if (topSensor == 1 && bottomSensor == 0) { 
    if (isMovingUp) { // Если двигались вверх
      digitalWrite(6, 0); // Останавливаем движение вверх
      isMovingUp = false; // Сбрасываем флаг движения вверх
      previousTime = millis(); // Запоминаем время начала паузы
    }

    // Проверяем, прошло ли достаточно времени для паузы вверху
    if (!isMovingDown && (millis() - previousTime >= pauseAtTop)) {
      digitalWrite(7, 1); // Начинаем движение вниз
      isMovingDown = true; // Устанавливаем флаг движения вниз
    }
  }

  // Если каретка достигла нижней точки
  if (topSensor == 0 && bottomSensor == 1) { 
    if (isMovingDown) { // Если двигались вниз
      digitalWrite(7, 0); // Останавливаем движение вниз
      isMovingDown = false; // Сбрасываем флаг движения вниз
      previousTime = millis(); // Запоминаем время начала паузы
    }

    // Проверяем, прошло ли достаточно времени для паузы внизу
    if (!isMovingUp && (millis() - previousTime >= pauseAtBottom)) {
      digitalWrite(6, 1); // Начинаем движение вверх
      isMovingUp = true; // Устанавливаем флаг движения вверх
    }
  }
}

вот полностью рабочий код с паузами по усмотрению пользователя.

Благодарю всех откликнувшихся, камни в мой огород пригодились, я построил забор :smiley: