Старт/конец событий с помощью milis
Я хочу запустить реле, запустить его на 3 секунды, остановить на 10 секунд и повторить.
Я не могу использовать задержку, потому что у меня моторный драйвер запускается/останавливается каждые 100 мили.
Поэтому я собрал этот код, но он не работает. Любая помощь приветствуется.
Задержка 500 мс, чтобы остановить слишком много отладочной информации.
Кроме того, по какой-то причине tenSecondsBool переключается в значение true, как только вы запускаете код.
unsigned long threeSeconds=3000; // время, которое нам нужно ждать
unsigned long threeSecondsMillis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long fourSeconds=7000; // время, которое нам нужно ждать
unsigned long fourSecondsMillis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long previousMillis=0; //millis() возвращает беззнаковое длинное значение.
bool ledState = false; // переменная состояния для светодиода
bool led2State = false; // переменная состояния для светодиода
unsigned long tenSecondMilis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long tenSeconds=10000; // время, которое нам нужно ждать
unsigned long paliGasiMilis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long paliGasi=1000; // время, которое нам нужно ждать
unsigned long ventMilis=0; //millis() возвращает беззнаковое длинное значение.
unsigned long ventInt=100; // время, которое нам нужно ждать
bool threeSecondBool = false;
bool tenSecondBool = false;
int Fin1 = D7;
#define enA D1
#define in1 D2
#define in2 D3
#define button 4
int rotDirection = 0;
int pressed = false;
void setup() {
Serial.begin(9600); // отправка и получение на скорости 9600 бод
pinMode(enA, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(button, INPUT);
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
pinMode(Fin1, OUTPUT);
digitalWrite(Fin1, HIGH);
threeSecondBool = false;
tenSecondBool = false;
}
void loop() {
unsigned long currentMillis = millis(); // получаем текущее время
if ((unsigned long)(currentMillis - tenSecondMilis) >= tenSeconds) {
Serial.print("---------------\n");
Serial.print("10 second end\n");
Serial.print("---------------\n");
tenSecondBool = true;
tenSecondMilis = millis();
}
Serial.print("10 second bool = ");
Serial.print(tenSecondBool);
Serial.print("\n");
Serial.print("3 second bool = ");
Serial.print(threeSecondBool);
Serial.print("\n");
if (tenSecondBool) {
if ((unsigned long)(currentMillis - threeSecondsMillis) >= threeSeconds) {
Serial.print("---------------\n");
Serial.print("3 second end\n");
Serial.print("---------------\n");
threeSecondBool = true;
threeSecondsMillis = millis();
}
}
if (!tenSecondBool && threeSecondBool){
Serial.print("Both triggered!\n");
digitalWrite(Fin1, HIGH);
}
if (!tenSecondBool && !threeSecondBool){
Serial.print("Both triggered!\n");
digitalWrite(Fin1, HIGH);
}
if (tenSecondBool && threeSecondBool){
threeSecondBool = false;
tenSecondBool = false;
digitalWrite(Fin1, LOW);
}
delay(500);
if ((unsigned long)(currentMillis - ventMilis) >= ventInt) {
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
ventMilis = millis();
} else {
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
}
}
@R0b0tn1k, 👍1
2 ответа
Лучший ответ:
Если вам нужен таймер с миллисекундами и разными интервалами, вы можете изменить интервал.
Для начала я использую Мигание без задержки и заимствовал "relay_is_on" из ответа автора Эдгар Боне.
unsigned long previousMillis;
unsigned long interval;
bool relay_is_on;
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (relay_is_on) {
// Реле было включено, теперь выключите его.
interval = 10000;
digitalWrite (relayPin, LOW);
relay_is_on = false;
} else {
// Реле было выключено, теперь включите его.
interval = 3000;
digitalWrite (relayPin, HIGH);
relay_is_on = true;
}
}
}
Глобальным переменным можно задать начальное значение (например, 3000 для интервала) или их можно установить в функции setup(). Вы должны выбрать, с чего вы хотите начать. Например, возможна задержка в одну секунду или одну минуту перед запуском.
Ваш код несколько сбивает с толку, вероятно, потому, что в нем слишком много переменные. Для выполнения того, что вы описываете, программе нужно только помните две вещи:
- находится ли реле во включенном или выключенном состоянии?
- когда в последний раз реле меняло состояние?
Они могут быть представлены следующим образом:
bool relay_is_on = false;
unsigned long last_relay_change = 0;
Тогда я рекомендую вам использовать описательные имена для ваших переменных и
константы. Вызов константы threeSeconds
бесполезен. У него нет
дополнительная ценность по сравнению с простым вводом 3000
. Имея константу с именем
RELAY_ON_TIME
делает его более понятным для чего он предназначен. Это
общее соглашение называть константы заглавными буквами, чтобы они стояли
out относительно переменных:
const uint8_t RELAY_PIN = ...;
const unsigned long RELAY_ON_TIME = 3000; // 3 s ON
const unsigned long RELAY_OFF_TIME = 10000; // 10 s OFF
Благодаря этому можно периодически включать и выключать реле. достигается следующим образом:
void loop()
{
unsigned long now = millis();
if (relay_is_on && now - last_relay_change >= RELAY_ON_TIME) {
// Выключать.
digitalWrite(RELAY_PIN, LOW);
relay_is_on = false;
last_relay_change = now;
}
if (!relay_is_on && now - last_relay_change >= RELAY_OFF_TIME) {
// Включать.
digitalWrite(RELAY_PIN, HIGH);
relay_is_on = true;
last_relay_change = now;
}
}
- Использование millis() и micros() внутри процедуры прерывания
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
- Получение BPM из данного кода
- Как считать время в секундах?
- Создание таймера с использованием часов реального времени с указанием времени начала и остановки
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect