millis

Valerman
Offline
Зарегистрирован: 06.01.2020

Подскажите пожалуйста. Хочу сделать, что-то вроде светодиодного предупреждения. Когда температура поднимается выше нормы, то светодиод горит, когда поднимается до критической отметки начинает мигать. Хотел использовать millis, но я не понимаю как это сделать. Если с просто горением светодиода все ясно, то как сделать, что бы он мигал и не тормозил скетч? Мигать должен до снижения температуры. 

if ( t >= 30 &&  t < 40) {

  digitalWrite(ledPin, HIGIH); 

} else if (t > 40) {

.........

 

Как продолжить дальше, если температура превысила 40? что бы диод мигал. Буду рад помощи. 

 

 

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

См. статью "Blink без delay".

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

... и использовать несколько раз в одной реализации!

Valerman
Offline
Зарегистрирован: 06.01.2020
#include <DallasTemperature.h>             
#include "DHT.h"         

#define ledPin 13
#define DHTPIN 7                            
#define DHTTYPE DHT22                      
DHT dht(DHTPIN, DHTTYPE);                    

unsigned long last_time = 0;               
void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600); // устанавливаем последовательное соединение
  dht.begin();
}

void siglan() {
  if (dht.readHumidity() >= 30) {
    if (millis() - last_time > 2000) {
      last_time = millis();      
      digitalWrite(ledPin,!digitalRead(ledPin));
    }   
    Serial.println("h>30"); 
  }
  if (dht.readHumidity() < 29) {
    digitalWrite (ledPin, HIGH);
    Serial.println("h<29");
  }  
}

void loop() {
siglan();
}

Когда переполнится unsigned long last_time, не зависнет ли ардуино? Или она сама скинет значение millis?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Valerman пишет:

Когда переполнится unsigned long last_time, не зависнет ли ардуино? Или она сама скинет значение millis?

1. Не зависнет;

2. При переполнении значение переменной last_time заворачивается на начало.

Valerman
Offline
Зарегистрирован: 06.01.2020

Спасибо. А как то можно этот код улучшить или оптимизировать? 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Valerman пишет:

Спасибо. А как то можно этот код улучшить или оптимизировать? 

Можно. Например, внутри функции siglan читать в переменную с датчика один раз, а не дважды. Затем: смысла читать из датчика при каждом проходе loop - нет никакого, достаточно читать раз в N времени.

Вы что хотите сделать? Читать из датчика и если значение превышает N влажности, то мигать светодиодом? Вот, как вариант:

#include "DHT.h"         

#define ledPin 13

#define DHTPIN 7                            
#define DHTTYPE DHT22                      
#define DHT_READ_FREQUENCY	2000 // через сколько миллисекунд читаем с датчика?
#define BLINK_FREQUENCY		500 // частота смены состояния светодиода, миллисекунд

DHT dht(DHTPIN, DHTTYPE);                    
bool blinkEnabled = false;
uint32_t blinkTimer = 0;
uint32_t dhtReadTimer = 0;
uint8_t lastKnownHumidity = 0;

uint8_t readFromDHT()
{
	if(millis() - dhtReadTimer >= DHT_READ_FREQUENCY)
	{
		lastKnownHumidity = dht.readHumidity();
		dhtReadTimer = millis();
		
	}
	
	return lastKnownHumidity;
}

void setup() 
{
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600); // устанавливаем последовательное соединение
  dht.begin();
}


void loop() 
{
	if(blinkEnabled)
	{
		if(millis() - blinkTimer >=  BLINK_FREQUENCY)
		{
			digitalWrite(ledPin,!digitalRead(ledPin));
			blinkTimer = millis();
		}
	}
		
	uint8_t humidity = readFromDHT();
	
	if(humidity < 29)
	{
		if(blinkEnabled)
		{
			blinkEnabled = false;
			digitalWrite (ledPin, HIGH);
		}
	}
	else
	if(humidity >= 30)
	{
		if(!blinkEnabled)
		{
			blinkEnabled = true;
			blinkTimer = millis();			
		}
	}
}

С датчика читается раз в 2 секунды, смена состояния светодиода - каждые полсекунды, если сработала уставка.

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

Или покороче (для человека):

const uint32_t blinkFreq = 1000;
const uint32_t blinkFactor = 0;
...
void loop() 
{
  digitalWrite(ledPin, millis() % blinkFreq > blinkFactor);
  uint8_t humidity = readFromDHT();
  if(humidity < 29) {
    blinkFactor = 0;
  }
  if(humidity >= 30) {
    blinkFactor = blinkFreq / 2;
  }
}

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Или покороче (для человека):

У меня просто махонький заход: писать в порты только тогда, когда что-то поменялось. Пунктик, короче :)

nik182
Offline
Зарегистрирован: 04.05.2015

DIYMan пишет:

sadman41 пишет:

Или покороче (для человека):

У меня просто махонький заход: писать в порты только тогда, когда что-то поменялось. Пунктик, короче :)

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

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

nik182 пишет:

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

digitalWrite всяко медленнее, чем одна проверка if. Ессно, я понимаю целесообразность, и руководствуюсь ровно тем, что вы описали ;)