не может вернуть значение с float из функции
Я хочу установить 2-секундную задержку для считывания температуры, но задержка millis() не применяется.
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
Time t;
LiquidCrystal_I2C lcd(0x27, 16, 2);
DS3231 rtc(SDA, SCL);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
const int OnHour = 23;
const int OnMin = 42;
const int checkTemp = 2000;
const int checkTempinterval = 0;
void setup() {
Serial.begin(115200);
pinMode(3, OUTPUT);
lcd.begin();
lcd.backlight();
rtc.begin();
}
void loop() {
t = rtc.getTime();
float testTemp;
testTemp = temperature();
lcd.setCursor(0,0);
lcd.print(testTemp);
lcd.print(" ");
lcd.print(rtc.getTimeStr());
lcd.setCursor(0,1);
lcd.print(rtc.getDOWStr());
lcd.print(" ");
lcd.print(rtc.getDateStr());
if(testTemp >= 28){
digitalWrite(3,HIGH);
}else{
digitalWrite(3,LOW);
}
// if(t.hour == OnHour && t.min == OnMin){
// цифровая запись(3,ВЫСОКИЙ);
// }еще{
// цифровая запись(3,НИЗКИЙ);
// }
}
float temperature(){
unsigned long currenttime = millis();
if(currenttime - checkTempinterval >= checkTemp){
sensors.requestTemperatures();
float testTemp = sensors.getTempCByIndex(0);
currenttime = checkTempinterval;
return testTemp;
}
}
@ElectronSurf, 👍1
Обсуждение2 ответа
Лучший ответ:
Я вижу 2 проблемы с вашим кодом:
Возврат значения из функции: Если вы хотите вернуть значение из функции, вы должны убедиться, что в любом случае
return x выполняется внутри функции в функцииtemperature(), которая у вас сейчас есть, если это оператор if:if(currenttime - checkTempinterval >= checkTemp){Внутри него находится единственный оператор
return. Это означает, что если функция вызывается до следующего времени измерения, она ничего не вернет. Обычно компилятор выдает вам как минимум предупреждение об этом (возможно, вам нужно включить предупреждения в настройках Arduino IDE).Здесь вы также должны подумать о том, что вы хотите вернуть, если никакое измерение фактически не выполнялось. Вы хотите вернуть значение ошибки (например,
-300; значение ошибки не должно находиться в допустимых данных)? Затем сделайте это после оператораif. Или вы хотите, чтобы он просто возвращал последнее измеренное значение? Затем объявите переменную (либо в глобальной области видимости, то есть вне какой-либо функции, либо в локальной области видимости, то есть внутри функции, но статической, что означает, что значение будет сохраняться между выполнениями функций). Сохраните измеренные температуры в эту переменную и верните ее после оператораif.Если вы это сделаете, подумайте, что это значит для остального кода. Например, если вы возвращаете значение ошибки, в настоящее время оно также будет отображаться вашим кодом.
Правильное выполнение кода
millis(): что вы делаете неправильно, так это то, что вы обновляете неправильную переменную внутриifзаявление. В настоящее время вы записываете значениеcheckTempinterval(которое является временем последнего измерения) в переменнуюcurrenttime. Переменнаяcurrenttimeбыла объявлена локально (то есть внутри функции) с помощьюunsigned long currenttime = millis();Локальные переменные присутствуют только во время выполнения функции, в которой они объявлены. Когда микроконтроллер выполняет оператор
return, он отбрасывает все локальные переменные, освобождая ОЗУ для другие переменные. Это означает, что в настоящее время вы сохраняете значение внутри переменной, которое удаляется сразу после него.На самом деле вы хотели сделать наоборот:
checkTempinterval = currenttime;checkTempinterval— это глобальная переменная. Он будет оставаться в оперативной памяти в течение всего выполнения программы. Поскольку он содержит время последнего измерения, вы записываете в него текущее время при измерении.Очень важно: в настоящее время
checkTempintervalопределяется какconst int, что означает постоянное целое число. Эта переменная не должна быть постоянной, так как мы хотим изменить значение (обновить время последнего измерения). Также вы не должны использовать здесьint, потому что диапазон его значений доходит только до 32767, что составляет 32 секунды при использовании сmillis(). После этого он переполнится до отрицательных значений. Лучше использовать тип возвращаемого значенияmillis():unsigned long. Он имеет 4 байта (вместо 2 байтовints) и переполнится только через 49 дней. Если вы используете этот тип переменной только для вещей сmillis(), даже это переполнение не будет проблемой.
Вы можете использовать функцию millis() для создания "таймера", который будет получать показания датчика каждые 2 секунды. Скетч BlinkWithoutDelay.ino должен поставляться с Arduino IDE, но если его нет, его можно найти здесь: BlinkWithoutDelay.
Я использовал именно этот скетч с некоторыми изменениями, чтобы отображать результаты на последовательном мониторе, а не мигать светодиодом. Когда вы что-то создаете, использование последовательного монитора может помочь вам устранить ошибки в скетче.
Пожалуйста, прочтите комментарии к коду в следующем скетче. Как только вы заработаете это с вашим кодом, вы сможете решить, нужна вам функция или нет.
// Сохраняем последний раз, когда вы проверяли датчик.
unsigned long previousMillis = 0;
// интервал проверки датчика (миллисекунды)
const long interval = 2000;
void setup() {
Serial.begin(9600);
}
void loop() {
// здесь вы бы разместили код, который должен выполняться все время.
// Получить текущее время.
unsigned long currentMillis = millis();
// Проверяем, не пора ли проверить показания датчика.
if (currentMillis - previousMillis >= interval) {
// сохранить последний раз, когда вы проверяли датчик.
previousMillis = currentMillis;
// Здесь вы добавляете код, который проверяет датчик.
// Тестовый вывод.
Serial.println("Checking Sensor");
}
}
- Эмуляция 1-проводных устройств
- Невозможно преобразовать 'int (*)[size]' в 'int**': Cannot convert 'int (*)[size]' to 'int**'
- Как удалить элемент из массива arduino?
- Есть ли функция Adafruit для инвертирования цветов моего экрана для языка Arduino?
- Как передать несколько переменных в функцию?
- Ошибка компиляции в nodeMCU вместе с датчиком температуры oneWire ds18b20 и ЖК-дисплеем 2x16 (не I2C)
- Как вернуть значение массива символов в функции Arduino IDE?
- DS1820 плохие показания 4-го датчика
Во-первых, не все пути выполнения возвращают значение, во-вторых, почему вы делаете:
currenttime = checkTempinterval;, это бессмысленно, так как после возврата оно больше не будет существовать., @KIIVВ вашем примере кода нет ничего под названием «мини»., @st2000
@KIIV, поэтому я не могу вернуть значение из sensor.getTempCByIndex(0);? он читает температуру, но задержка не применяется..., @ElectronSurf
Вы можете, но код не делает этого в случае, если условие if не выполняется., @KIIV
@KIIV, так какое решение?, @ElectronSurf
Удалите все это и начните с нуля. Включить все предупреждения! Не используйте никаких ветвей в Temperature(), возможно, даже забудьте о функциях, пока вы не поймете концепцию локальных переменных, их область действия и существование. Просто используйте задержку (2000), прочитайте rtc, запросите температуру, распечатайте результаты, @KIIV
это вопрос, и, любезно ответив на него, вы можете помочь мне «понять концепцию локальных переменных», и я не хочу использовать задержку!, @ElectronSurf
Также спрашивали здесь: https://forum.arduino.cc/index.php?topic=621590.0, @Jot
@Jot "Детективное достижение разблокировано"!, @ElectronSurf
Тем более в чем вопрос? Я не вижу ни одного., @MichaelT