Не работает таймер на millis

Добрый день. Начал осваивать arduino и столкнулся с тем, что не выходит реализовать таймер на millis.
В общем идея такая, имеется некий импульсный насос, работает через реле и по задумке должен управляться по bluetooth/монитор порта и дозировать нужный объем. Написал небольшой простейший код с использованием delay в цикле for, который подает нужное количество импульсов. Скетч работает без проблем, довольно точно подается нужный объем, но хотелось бы реализовать все с использованием millis, дабы контроллер не висел трупом на время исполнения delay, т.к. планирую повесить на одну ардуинку датчики, реле и т.д.
(Прилагаю два скетча один с delay (работает чётко как надо), второй по примеру из мануала arduino на millis (реле загорается и не тухнет)).
Скетч с delay()

#define RELE1_PIN 7
float herc;
float vol;
float i;

void setup() {
Serial.begin(9600);
while (!Serial) {
}
pinMode(RELE1_PIN,OUTPUT);
delay (1000);
}

void loop() {
  if (Serial.available()>0) {
   vol = Serial.parseFloat();
   delay (2);
   herc = ((vol+0.006532777)/0.0219799796);
    for (i=0; i<=herc; i++) {
       digitalWrite(RELE1_PIN, HIGH);
       delay(10);
       digitalWrite(RELE1_PIN, LOW);
       delay(10);
      } 
    }  
}

Скетч с millis () после послания абсолютно любого символа в монитор порта, просто загорается и соответственно так же, с любого символа гаснет.

const int ledPin = 7;
int ledState = LOW;
unsigned long previousMillis = 0;
const long interval = 500;
float herc;
float vol;

void setup() {
  Serial.begin(9600);
  while (!Serial) {}
  pinMode(ledPin, OUTPUT);
}

void loop() {
unsigned long currentMillis = millis();
if (Serial.available()>0) {
  vol= Serial.parseFloat();
  herc = ((vol+0.006532777)/0.0219799796);
 if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
}
}```

Вставьте код как положено

Все работает именно так, как написано в скетче. То, что это не совпадает с вашими желаниями, говорит только о том, что вы не продумали, как нужно. Постарайтесь мысленно пройтись по вашему коду, “выполняя” его в голове, и сами все поймете.

Тупая замена delay() на millis() ничего не даст, т.к. это абсолютно разные принципы работы.

1 лайк

https://forum.arduino.ru/t/zamena-delay-s-pomoshhyu-millis/10308

Обратите внимание, что в скетче с миллис Вы вообще не используете данные, полученные из порта. Это одно необходимое исправление в логике.
Другое - это то, что непосредственно дёргание пина насоса находится внутри условия “если пришла команда”. Надо вынести наружу!

Вот очень примерный алгоритм действий в loop:
Если пришла команда, то считаем и запоминаем необходимое число импульсов и например взводим флаг “надо качать!”.
А дальше смотрим этот флаг.
Если надо качать, то дёргаем ножкой, проверяя интервал переключения и считая, сколько раз дёрнули. Когда дойдём до нужного числа, сбрасываем флаг.
Если не надо качать - ничего не делаем.

Когда это реализуете, то должны появиться уточняющие вопросы, которых нет в скетче с делей. Например, что нужно делать, если команда пришла, когда уже качаем? Но это можно уже потом разрулить.

ошибка здесь, пока символ по сериалу не пришел остальное всё висит.

Ну и желательно вообще разобраться, как асинхронно такие вещи писать, типа Случилось - Действие. Там просто в Лууп носится всё без остановки и если какое-то условие выполняется то что-то происходит; и никто никого не ждет. Ну это я так, на бытовом тсказать уровне пытаюсь объяснить способ.

Еще порабатайте в этом направлении.

// В объявлении:
unsigned long time;

// В setup:
time=millis()+5000;

// В loop:
if (millis()>=time)
{
// здесь что-то свое
	time=millis()+5000;
}

Как-то так.

почитайте что-нибудь про переполнение, прежде чем давать плохие советы

Для начала пусть так попробует. Потом можно будет говорить о 50-ти дневной работе.

Вы сами-то понимаете, в чем разница? Никаких усложнений кода не требуется, всего лишь написать правильно.

if (millis()-time>0)
{
	// здесь что-то свое
	time=millis()+5000;
}

или так:

if (millis()-time>5000)
{
	// здесь что-то свое
	time=millis();
}

Не надо так пробовать. И советы вам пока рано давать

Не “или так”, а так и только так

1 лайк

if (millis()-time>5000)
{
// здесь что-то свое
time=millis();
}

Ну на 50 дней для опытов ему бы хватило.

Вам уже сказали, это вредный опыт. Не нужно плодить говнокод “и так сойдет”.

Спойлер

Нужно всегда стараться все делать хорошо. Плохо само получится

И создало бы уверенность, что все нормально. А редкие глюки девайса, работающего 24/7 всегда можно списать на китайскую ардуину ))

А на что можно списать это?

void loop()
{

    if (millis()-time>250)
    {
        trigger=!trigger;
        digitalWrite(13, trigger); // здесь обычное мигание светодиода
        time=millis();
    }
    

    if (millis()-time2>10000)
    {
    	trigger2=!trigger2;
      // А здесь получаю данные с BMP180 (температуру)
      time2=millis();
    }
}

Так вот. Несколько часов все было нормально, а затем данные о температуре “застыли”, светодиод продолжал мигать. Восстановилось после перезагрузи МК.

не вижу в коде никакой температуры

2 лайка
  1. Нужно код выкладывать полностью (чтобы можно было его у себя “запустить”)
  2. Если используются какие-либо сторонние библиотеки - нужно указывать ссылку на скачивание этих библиотек.

Я вообще стараюсь вот так делать:

// К примеру:
#include "kakmyc_btn.h"     // https://github.com/kakmyc-github/kakmyc_btn