Непонятное влияние оператора Serial.Println

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Поставлена задача в 10-секундном цикле на 2 секунды зажигать светодиод. При наличии в скетче оператора Serial.Println программа нормально работает. Стоит его закомментировать, начинается частое мигание светодиода, похоже, со скважностью 0,5. Что делает Serial.Println? Как избавиться от этой беды?

01      //АРДУИНО МЕГА 2560
02int n=0;          //Количество опросов
03int light=2000;   //Время зажженного диода
04unsigned long time_diod;   //Переменная времени опроса диода
05void setup()
06{
07  Serial.begin(115200);
08  pinMode(8, OUTPUT); //пин вывода на диод
09}
10 
11void loop()
12{
13   if (millis() - time_diod > 100) //Опрос каждые 100 мсек
14    {
15      n++;
16      if(n<light) {digitalWrite (8,HIGH);}
17      else {digitalWrite (8,LOW);}
18      if(n==10000) {n=0;}
19      time_diod=millis;
20      Serial.println(n);
21    }
22}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

time_diod=millis; << вот это работает?

b707
Offline
Зарегистрирован: 26.05.2017

Sonologist пишет:

Поставлена задача в 10-секундном цикле на 2 секунды зажигать светодиод. При наличии в скетче оператора Serial.Println программа нормально работает.

на самом деле у вас программа совершенно неверно написана. Если бы не ошибка, которую заметил Садман - у вас диод горел бы не 2 секунды, а 3 минуты, а потом выключался на 15 минут.

Кто вас так учил временные интервалы отмерять?

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Работает. Такая же конструкция

   if (millis() - time_ds18b20 > 850)
    {
      // Код опроса датчика температуры и индикации его на 7-сегментном модуле
      time_ds18b20=millis;
    }

нормально  определяет и показывает температуру на модуле. Я просто вместо опроса датчика поставил фрагмент с миганием светодиода.

b707
Offline
Зарегистрирован: 26.05.2017

Sonologist пишет:

Работает. Такая же конструкция

   if (millis() - time_ds18b20 > 850)
    {
      // Код опроса датчика температуры и индикации его на 7-сегментном модуле
      time_ds18b20=millis;
    }

нормально  определяет и показывает температуру на модуле. Я просто вместо опроса датчика поставил фрагмент с миганием светодиода.

блин,  вы еще и спорить будете?

Что такое millis ? И чем оно отличается от millis() - как вы думаете?

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

b707 пишет:

Кто вас так учил временные интервалы отмерять?

Дык сам кумекал... 

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Вот я пень-то обоссанный!!!!  Спасибо, братцы!

b707
Offline
Зарегистрирован: 26.05.2017

Sonologist пишет:

Дык сам кумекал... 

дык неправильно

b707
Offline
Зарегистрирован: 26.05.2017

Sonologist пишет:

Вот я пень-то обоссанный!!!!  Спасибо, братцы!

не расслабляйтесь. Это только первая ошибка. А их там еще есть...

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

b707 пишет:

А их там еще есть...

Даже не сомневаюсь, но:

Раз в 100 мсек прибавляю к счетчику единичку, и пока он не досчитает до нужного числа, диод горит. При превышении - гаснет. По достижению 10 секунд счетчик обнуляю. Начинается новый цикл. 

Вроде, логично, но в чем ошибка?

sadman41
Offline
Зарегистрирован: 19.10.2016

10000 проходов * 100 мс = ?

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Уже исправил:

01      //АРДУИНО МЕГА 2560
02int n=0;          //Количество опросов
03int light=20;   //Время зажженного диода
04unsigned long time_diod;   //Переменная времени опроса диода
05void setup()
06{
07  pinMode(8, OUTPUT); //пин вывода на диод
08}
09 
10void loop()
11{
12   if (millis() - time_diod > 100) //Опрос каждые 100 мсек
13    {
14      n++;
15      if(n<light) {digitalWrite (8,HIGH);}
16      else {digitalWrite (8,LOW);}
17      if(n==100) {n=0;}
18      time_diod=millis();
19    }
20}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Так вот можно сэкономить на буквочках:

digitalWrite(8, (n < light));

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Спасибо, на такие укорочения кода - мой следующий этап.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А какой глубокий смысл квантовать время по 0.1с, тогда как наименьший квант в задаче 2с? (10 делится на 2)

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

andriano пишет:

А какой глубокий смысл квантовать время по 0.1с, тогда как наименьший квант в задаче 2с? (10 делится на 2)

Тут все очень просто и выявлено на основании практики. Большинство клапанов, которые работают на отборе продукта управляемо дозируют отбор при времени открытого состояние 0,1 сек и больше. Приведенный мной скетч - пробный. На самом деле зажигаться будет не просто светодиод, а оптрон мос3023 для тиристорного управления клапаном. И параметр "light" - настраиваемая величина скважности работы клапана (100 шагов) при постоянном 10-секундном цикле.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Sonologist пишет:

andriano пишет:

А какой глубокий смысл квантовать время по 0.1с, тогда как наименьший квант в задаче 2с? (10 делится на 2)

Тут все очень просто и выявлено на основании практики. Большинство клапанов, которые работают на отборе продукта управляемо дозируют отбор при времени открытого состояние 0,1 сек и больше. Приведенный мной скетч - пробный. На самом деле зажигаться будет не просто светодиод, а оптрон мос3023 для тиристорного управления клапаном. И параметр "light" - настраиваемая величина скважности работы клапана (100 шагов) при постоянном 10-секундном цикле.

Я все равно не понял, какой смысл вводить новый квант времени 0.1с, когда в Ардуине уже есть 1мс 1мкс. Зачем плодить лишние сущности?

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

andriano пишет:

Я все равно не понял, какой смысл вводить новый квант времени 0.1с, когда в Ардуине уже есть 1мс 1мкс. Зачем плодить лишние сущности?

Простите, я все-таки Вас не понял. Показатель "light" не константа и будет настраиваться в промежутке от 100 до 10000 мсек. Как иначе это сделать?

b707
Offline
Зарегистрирован: 26.05.2017

Sonologist пишет:

Простите, я все-таки Вас не понял. Показатель "light" не константа и будет настраиваться в промежутке от 100 до 10000 мсек. Как иначе это сделать?

что мешает сравнивать интервал непосредственно с миллис, без промежуточных опросов каждые 100 мс?

1if (millis() - time_diod > light) //light в промежутке от 10 до 10000 мс
2   {

 

SLKH
Offline
Зарегистрирован: 17.08.2015

Sonologist пишет:

Простите, я все-таки Вас не понял. Показатель "light" не константа и будет настраиваться в промежутке от 100 до 10000 мсек. Как иначе это сделать?

loop()

{

если (с начала цикла прошло 10 секунд) {запомнить новое начало цикла; включить диод; }

если (с начала цикла прошло light) {выключить диод;}

 

// сделать чё те надо;

// присвоить значение light в зависимости от чё ты хошь;

}

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

спасибо, теперь понятно! :)

walt88
Offline
Зарегистрирован: 14.04.2019

Sonologist пишет:

Поставлена задача в 10-секундном цикле на 2 секунды зажигать светодиод

А не задумывались если к примеру захочется поморгать не одним а 5-6ю светодиодами ? и все с разными интервалами, в таком случае рекомендую обротить внимание на классы, вешь мощная и иногда просто необходимая

01uint8_t sendPin = 13;
02uint8_t sendPin2 = 10;
03 
04class larduino_Blink{
05public:     larduino_Blink(uint8_t, uint32_t, uint32_t); //  Создание экземпляра класса (№ вывода,  время работы, время таймаута)
06    void      Think(void);      
07private:
08    uint32_t _Timeout;
09    uint32_t _WorkTime;
10    uint32_t _startTime;
11    int _pin;
12    bool _togle;
13};
14 
15larduino_Blink::larduino_Blink(uint8_t pin, uint32_t WorkTime, uint32_t Timeout){
16    pinMode(pin, OUTPUT);
17    _pin = pin;
18    _WorkTime = WorkTime;
19    _Timeout = Timeout;
20    _startTime = millis();
21}
22 
23void larduino_Blink::Think(){
24    if((millis() - _startTime) > (_togle ? _Timeout : _WorkTime)){
25        digitalWrite(_pin, _togle = !_togle);
26        _startTime = millis();
27    }
28}
29 
30larduino_Blink Blink( sendPin, 200, 1000); // моргаем на 13 пин  (№ вывода,  время работы, время таймаута)
31larduino_Blink Blink2( sendPin2, 2000, 8000); // моргаем на 10 пин  (№ вывода,  время работы, время таймаута)
32 
33void setup() {}
34 
35void loop() {
36    Blink.Think();
37    Blink2.Think();
38}

 

Sonologist
Sonologist аватар
Offline
Зарегистрирован: 08.06.2018

Спасибо, пока такой надобности нет, но этот скетч переписал в загашник. Очень полезно. Буду изучать.