не может вернуть значение с 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 байтовint
s) и переполнится только через 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?
- Как передать несколько переменных в функцию?
- Ошибка компиляции в nodeMCU вместе с датчиком температуры oneWire ds18b20 и ЖК-дисплеем 2x16 (не I2C)
- Есть ли функция Adafruit для инвертирования цветов моего экрана для языка Arduino?
- Как вернуть значение массива символов в функции 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