Запуск сторонней функции в loop(), нужна помощь.
- Войдите на сайт для отправки комментариев
Вс, 10/01/2016 - 20:28
Здравствуйте, помогите пожалуйста разобраться с кодом. Коротко о проекте: сбор показаний с датчиков с интервалом в 2с, и плюс решил на борту шим регулятор одной кнопкой замутить. Раздельно эти функции выполняются на ура, а вот вместе из-за delay, обработка кнопки тормозит...пробовал проводить измерения сторонней функцией, а шим оставить в loop, но ничего не вышло...я так и не понял как вызвать функцию которая ничего не возвращает в loop. Может сделать вывод в серийный монитор из результатов измериний в loop, а сторонняя функция будет проводить измерения и передавать результаты в loop?
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT11
int vlagaPin = 3;
int vlagaVal = 0;
int switchPin = 8;
int ledPin = 11;
boolean lastButton = LOW;
boolean currentButton = LOW;
int ledLevel = 0;
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
dht.begin();
pinMode(switchPin, INPUT);
pinMode(ledPin, OUTPUT);
}
boolean debounce(boolean last)
{
boolean current = digitalRead(switchPin);
if (last != current)
{
delay(5);
current = digitalRead(switchPin);
}
return current;
}
void loop() {
currentButton = debounce(lastButton);
if (lastButton == LOW && currentButton == HIGH)
{
ledLevel = ledLevel + 51;
}
lastButton = currentButton;
if (ledLevel > 255) ledLevel = 0;
analogWrite(ledPin, ledLevel);
//__________________________________
float h = dht.readHumidity();
float t = dht.readTemperature();
vlagaVal = analogRead(vlagaPin);
Serial.print("Humidity: ");
Serial.print(h);
Serial.println(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C ");
Serial.print("Vlagnost' ");
Serial.println(vlagaVal);
delay(2000);
}
/*
void measurement() {
float h = dht.readHumidity();
float t = dht.readTemperature();
vlagaVal = analogRead(vlagaPin);
Serial.print("Humidity: ");
Serial.print(h);
Serial.println(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C ");
Serial.print("Vlagnost' ");
Serial.println(vlagaVal);
delay(2000);
}*/
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
Со светодиодом еще понятно, у него есть 2 состояния которые можно отследить и посчитать millis(), а как быть с задержкой после измерения 2х датчиков?
не используй delay !!!
примерно так (пока недописано, но думаю принцеп понятен):
//************************************************************************************************* // главный цикл //************************************************************************************************* void loop() { unsigned long time_loop_new; unsigned long time_pause; int button_temp; time_loop_new = millis(); // получим время начала цикла // -------------------------------------------------------------------------------------------- // обработка управления кнопками, должена идти как можно ближе к началу цикла button_temp = getPressedButton(); if (button_new != button_temp) { // изменилось состояние клавиатуры, запомним время и новое состояние button_new = button_temp; time_button_new = time_loop_new; } time_pause = getDelayTime(time_button_new, time_loop_new); if (time_pause <= BUTTON_TIME) { // ожидание минимальной паузы } else { if (button_new != button) { // сотояния клавиатуры изменилось, минимальная пауза выдержана if (button_new == BUTTON_NONE) { // кнопка отпущена // вызовем обработчик, при этом расчитаем время нажатие от события нажатия а не от нового события отпускания OnKeyUp (button, getDelayTime(time_button, time_button_new)); } else if (button != BUTTON_NONE) { // кнопка нажата, пока обработчик этого события мне не нужен, // по тому, что кнопка SELECT обрабатывается по таймеру двумя разными способами // здесь ничего не делаем, код оставляю для расширения в других проектах } else { // смена нажатой кнопки на другую, пока обработчик этого события мне не нужен // по тому, что мы работаем не по событию нажатия, а по событию отжатия // здесь ничего не делаем, код оставляю для расширения в других проектах } // изменения клавиатуры отработаны, теперь запомним новое состояние time_button = time_loop_new; button = button_new; } else if ((button_new == button) && (button != BUTTON_NONE)) { // есть какая-то зажатая кнопка if ((button == BUTTON_SELECT) && (time_pause >= BUTTON_TIME_LONG)) { // кнопка SELECT нажата достаточно долго для перехода в режим SETUP // это пока не реализовано, мы пойдем другим путем и будем передовать время удержания в событие отжатия кнопки // здесь ничего не делаем, код оставляю для расширения в других проектах } } } // -------------------------------------------------------------------------------------------- // получение актуальной температуры time_pause = getDelayTime(time_temp, time_loop_new); if (time_pause > TIME_GET_THERMOMETR) { // ReadThermometer(); } // -------------------------------------------------------------------------------------------- // поиск ошибок/аварий и схожих ситуаций, ищет неподконтрольный разогрев/остывание или отсутствие показаний с термопары // -------------------------------------------------------------------------------------------- // расчет параметров для включения и выключения разогрева // -------------------------------------------------------------------------------------------- // обновление экрана, это последнее... time_pause = getDelayTime(time_anime, time_loop_new); if (time_pause > TIME_ANIME) { time_anime = time_loop_new; screen_out(true, false, false); } else { screen_out(false, false, false); } }delay нужно выкинуть. Просто вход в ту часть кода, где происходит измерение датчиков нужно делать раз в 2 сек., вот так например:
#define INTRVAL1 2000 #define INTRVAL2 50 #define INTRVAL3 200 unsigned int t1=0;, t2=0, t3=0, time; #define TIMER(t) (time-t) #define CLRTIMER(t) (t=time) void loop() { time=milles(); if (TIMER(t1)>INTERVAL1) { CLRTIMER(t1); //измерение датчиков } if (TIMER(t2)>INTERVAL2) { CLRTIMER(t2); //опрос кнопок } if (TIMER(t3)>INTERVAL3) { CLRTIMER(t3); //ШИМ } }Со светодиодом еще понятно, у него есть 2 состояния которые можно отследить и посчитать millis()
Вы неправильно поняли пример. Для того, чтобы посчитать millis не нужно отслеживать состояние светодиода. Состояние в том примере отслеживается только для того, чтобы его инвертировать (если горит, то потушить; если не горит, то зажечь). С millis это не связано. Для подсчета millis нужно не состояние, а событие. В Вашем случае событием будет чтение с датчика.
Как мне отслеживать и каждый раз перезапускать чтение с датчика dht например?
P/s Спасибо, действительно, можно разбить программу на временные отрезки с помощью if...else/ сейчас попробую
Получилось довольно таки просто. Теперь кнопка не тормозит и данные корректно приходят в серийный порт.
void loop() { currentButton = debounce(lastButton); if (lastButton == LOW && currentButton == HIGH) { ledLevel = ledLevel + 51; } lastButton = currentButton; if (ledLevel > 255) ledLevel = 0; analogWrite(ledPin, ledLevel); unsigned long currentMillis = millis(); if(currentMillis - previousMillis >= interval) { previousMillis = currentMillis; float h = dht.readHumidity(); float t = dht.readTemperature(); vlagaVal = analogRead(vlagaPin); Serial.print("Humidity: "); Serial.print(h); Serial.println(" %\t"); Serial.print("Temperature: "); Serial.print(t); Serial.println(" *C "); Serial.print("Vlagnost' "); Serial.println(vlagaVal); } }