Возникли проблемы с чтением нескольких термисторов с Arduino 2560
Я пытаюсь заставить свой код считывать несколько термисторов, и, похоже, я не совсем понимаю, как это правильно сделать, используя мой arduino 2560. Первая проблема заключается в том, что он считывает не больше, чем первый термистор. Следующая проблема - цикл for, который отображает текущую температуру, всегда показывает "ВЫКЛЮЧИТЬ", когда она ниже диапазона 60C.
Вот мой код:
/* Здесь у нас есть несколько констант, которые облегчают редактирование кода. Я пройдусь
по ним один за другим.
Считывание с АЦП может дать одно значение в одной выборке, а затем немного
отличаться в следующий раз. Чтобы исключить шумные показания, мы можем
несколько раз проверить вывод АЦП, а затем усреднить выборки, чтобы получить что-то более
достоверное. Эта константа используется в функции считывания термистора.
*/
const int SAMPLE_NUMBER = 10;
/ * Чтобы использовать бета-уравнение, мы должны знать наш другой резистор
в нашем резистивном делителе. Если вы используете что-то с большим допуском,
например, 5% или даже 1%, измерьте его и поместите свой результат здесь в омах. */
const double BALANCE_RESISTOR0 = 10060.0; //
const double BALANCE_RESISTOR1 = 10000.0;
const double BALANCE_RESISTOR2 = 10000.0;
const double BALANCE_RESISTOR3 = 10000.0;
const double BALANCE_RESISTOR4 = 10000.0;
const double BALANCE_RESISTOR5 = 10000.0;
const double BALANCE_RESISTOR6 = 10000.0;
const double BALANCE_RESISTOR7 = 10000.0;
const double BALANCE_RESISTOR8 = 10000.0;
const double BALANCE_RESISTOR9 = 10000.0;
// Это помогает рассчитать сопротивление термистора (подробности см. в статье).
const double MAX_ADC = 1023.0;
/ * Это зависит от термистора, и оно должно быть в техническом описании, или обратитесь к
статье о том, как рассчитать его, используя бета-уравнение.
Я должен был это сделать, но я бы попытался получить термистор с известной
бета-версией, если вы хотите избежать эмпирических вычислений. */
const double BETA = 3977.0;
/* Это также необходимо для уравнения преобразования, поскольку в качестве входных данных требуется "типичная" комнатная температура
. */
const double ROOM_TEMP = 295.950; // комнатная температура в Кельвинах
/ * Термисторы будут иметь типичное сопротивление при комнатной температуре, поэтому запишите это
здесь. Опять же, необходимо для преобразования уравнений. */
const double RESISTOR_ROOM_TEMP = 10980.0;
//===============================================================================
// Переменные
//===============================================================================
// Здесь мы сохраним текущую температуру
double currentTemperature = 0;
//===============================================================================
// Объявления выводов
//===============================================================================
//Входные данные:
int thermistorPin0 = 0; // Где АЦП производит выборку выходного сигнала резисторного делителя
int thermistorPin1 = 1;
int thermistorPin2 = 2;
int thermistorPin3 = 3;
int thermistorPin4 = 4;
int thermistorPin5 = 5;
int thermistorPin6 = 6;
int thermistorPin7 = 7;
int thermistorPin8 = 8;
// Результаты:
//===============================================================================
// Инициализация
//===============================================================================
void setup()
{
// Настройка скорости порта для сообщений последовательного окна
Serial.begin(9600);
}
//===============================================================================
// Главная
//===============================================================================
//===============================================================================
// Функции
//===============================================================================
/////////////////////////////
////// Считывающий термистор ///////
/////////////////////////////
double readThermistor()
{
// переменные, которые работают в этой функции
double rThermistor0 = 0; // Содержит значение сопротивления термистора
double rThermistor1 = 0;
double rThermistor2 = 0;
double rThermistor3 = 0;
double rThermistor4 = 0;
double rThermistor5 = 0;
double rThermistor6 = 0;
double rThermistor7 = 0;
double rThermistor8 = 0;
double tKelvin0 = 0; // Содержит расчетную температуру
double tKelvin1 = 0;
double tKelvin2 = 0;
double tKelvin3 = 0;
double tKelvin4 = 0;
double tKelvin5 = 0;
double tKelvin6 = 0;
double tKelvin7 = 0;
double tKelvin8 = 0;
double tCelsius0 = 0; // Температура удержания в градусах Цельсия
double tCelsius1 = 0;
double tCelsius2 = 0;
double tCelsius3 = 0;
double tCelsius4 = 0;
double tCelsius5 = 0;
double tCelsius6 = 0;
double tCelsius7 = 0;
double tCelsius8 = 0;
double adcAverage0 = 0; // Содержит среднее значение измерения напряжения
double adcAverage1 = 0;
double adcAverage2 = 0;
double adcAverage3 = 0;
double adcAverage4 = 0;
double adcAverage5 = 0;
double adcAverage6 = 0;
double adcAverage7 = 0;
double adcAverage8 = 0;
int adcSamples0[SAMPLE_NUMBER]; // Массив для хранения каждого измерения напряжения
int adcSamples1[SAMPLE_NUMBER];
int adcSamples2[SAMPLE_NUMBER];
int adcSamples3[SAMPLE_NUMBER];
int adcSamples4[SAMPLE_NUMBER];
int adcSamples5[SAMPLE_NUMBER];
int adcSamples6[SAMPLE_NUMBER];
int adcSamples7[SAMPLE_NUMBER];
int adcSamples8[SAMPLE_NUMBER];
/* Вычислить среднее сопротивление термистора:
Как упоминалось в верхней части кода, мы будем несколько раз пробовать вывод АЦП
чтобы получить кучу образцов. Небольшая задержка добавляется для правильного выполнения
выборки функции analogRead */
for (int i = 0; i < SAMPLE_NUMBER; i++)
{
adcSamples0[i] = analogRead(thermistorPin0); // считывание с вывода и сохранение
adcSamples1[i] = analogRead(thermistorPin1);
adcSamples2[i] = analogRead(thermistorPin2);
adcSamples3[i] = analogRead(thermistorPin3);
adcSamples4[i] = analogRead(thermistorPin4);
adcSamples5[i] = analogRead(thermistorPin5);
adcSamples6[i] = analogRead(thermistorPin6);
adcSamples7[i] = analogRead(thermistorPin7);
adcSamples8[i] = analogRead(thermistorPin8);
delay(10); // подождите 10 миллисекунд
}
/* Затем мы просто усредним все эти выборки для получения "более жесткого"
измерение. */
for (int i = 0; i < SAMPLE_NUMBER; i++)
{
adcAverage0 += adcSamples0[i]; // сложить все выборки . . .
adcAverage1 += adcSamples1[i];
adcAverage2 += adcSamples2[i];
adcAverage3 += adcSamples3[i];
adcAverage4 += adcSamples4[i];
adcAverage5 += adcSamples5[i];
adcAverage6 += adcSamples6[i];
adcAverage7 += adcSamples7[i];
adcAverage8 += adcSamples8[i];
}
adcAverage0 /= SAMPLE_NUMBER; // . . . усреднить его с / разделить
adcAverage1 /= SAMPLE_NUMBER;
adcAverage2 /= SAMPLE_NUMBER;
adcAverage3 /= SAMPLE_NUMBER;
adcAverage4 /= SAMPLE_NUMBER;
adcAverage5 /= SAMPLE_NUMBER;
adcAverage6 /= SAMPLE_NUMBER;
adcAverage7 /= SAMPLE_NUMBER;
adcAverage8 /= SAMPLE_NUMBER;
/* Здесь мы вычисляем сопротивление термистора, используя уравнение
, рассмотренное в статье. */
rThermistor0 = BALANCE_RESISTOR0 * ( (MAX_ADC / adcAverage0) - 1);
rThermistor1 = BALANCE_RESISTOR1 * ( (MAX_ADC / adcAverage1) - 1);
rThermistor2 = BALANCE_RESISTOR2 * ( (MAX_ADC / adcAverage2) - 1);
rThermistor3 = BALANCE_RESISTOR3 * ( (MAX_ADC / adcAverage3) - 1);
rThermistor4 = BALANCE_RESISTOR4 * ( (MAX_ADC / adcAverage4) - 1);
rThermistor5 = BALANCE_RESISTOR5 * ( (MAX_ADC / adcAverage5) - 1);
rThermistor6 = BALANCE_RESISTOR6 * ( (MAX_ADC / adcAverage6) - 1);
rThermistor7 = BALANCE_RESISTOR7 * ( (MAX_ADC / adcAverage7) - 1);
rThermistor8 = BALANCE_RESISTOR8 * ( (MAX_ADC / adcAverage8) - 1);
/* Здесь используется бета-уравнение, но оно отличается
из того, что описано в статье. Не волнуйся! Он был перестроен
алгебраически, чтобы дать "лучшую" формулу. Я призываю вас
попытаться самостоятельно манипулировать уравнением из статьи, чтобы получить
лучше в алгебре. А если нет, просто используйте то, что показано здесь, и возьмите это
как должное или введите формулу непосредственно из статьи, точно
как это показано. Любой способ сработает! */
tKelvin0 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor0 / RESISTOR_ROOM_TEMP)));
tKelvin1 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor1 / RESISTOR_ROOM_TEMP)));
tKelvin2 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor2 / RESISTOR_ROOM_TEMP)));
tKelvin3 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor3 / RESISTOR_ROOM_TEMP)));
tKelvin4 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor4 / RESISTOR_ROOM_TEMP)));
tKelvin5 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor5 / RESISTOR_ROOM_TEMP)));
tKelvin6 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor6 / RESISTOR_ROOM_TEMP)));
tKelvin7 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor7 / RESISTOR_ROOM_TEMP)));
tKelvin8 = (BETA * ROOM_TEMP) /
(BETA + (ROOM_TEMP * log(rThermistor8 / RESISTOR_ROOM_TEMP)));
/* Я буду использовать единицы измерения Цельсия для обозначения температуры. Я сделал это
просто чтобы я мог видеть типичную комнатную температуру, которая составляет 25 градусов
Цельсия, когда я впервые опробовал эту программу. Я предпочитаю Фаренгейт, но
Я оставляю на ваше усмотрение либо изменить эту функцию, либо создать
еще одна функция, которая преобразует между двумя единицами измерения. */
tCelsius0 = tKelvin0 - 273.15; // перевести кельвин в Цельсий
tCelsius1 = tKelvin1 - 273.15;
tCelsius2 = tKelvin2 - 273.15;
tCelsius3 = tKelvin3 - 273.15;
tCelsius4 = tKelvin4 - 273.15;
tCelsius5 = tKelvin5 - 273.15;
tCelsius6 = tKelvin6 - 273.15;
tCelsius7 = tKelvin7 - 273.15;
tCelsius8 = tKelvin8 - 273.15;
return tCelsius0; // Возвращает температуру в
return tCelsius1;
return tCelsius2;
return tCelsius3;
return tCelsius4;
return tCelsius5;
return tCelsius6;
return tCelsius7;
return tCelsius8;
}
void loop()
{
/* Основной цикл довольно прост, он выводит информацию о температуре в
последовательном окне. Сердце программы находится внутри считывающего термистора
функция. */
currentTemperature = readThermistor();
delay(3000);
/* Вот как вы можете действовать при
слишком высокой, слишком холодной или правильной температуре. */
if (currentTemperature > 0.0 && currentTemperature < 60.0)
{
Serial.print("It is ");
Serial.print(currentTemperature);
}
else (currentTemperature >= 60.0);
{
Serial.print("It is ");
Serial.print(currentTemperature);
Serial.println("C. SHUT OFF!");
}
}
Я не специалист в программировании, поэтому, если у вас есть какие-либо предложения, которые могли бы помочь, я был бы вам очень признателен.
@GarthDanti, 👍0
Обсуждение1 ответ
Добро пожаловать в Stack Exchange!
Проблема, вызывающая первую проблему, заключается в ваших нескольких операторах возврата в
функции readThermistor.
return
завершает работу функции, поэтому, когда код запускает return tCelsius0
, он завершает работу функции и не запускает ни один из последующих операторов return.
Попробуйте сохранить ваши температуры в массиве, а затем вернуть этот массив. Однако в любом случае вы также считываете только одно из значений в функции main()
.
Проблема, вызывающая вторую проблему, заключается в том, что у вас есть if
и else
. Чтобы правильно проверить ваше второе условие currentTemperature >= 60.0
, вам нужно иметь вместо него значение else if .
Большое вам спасибо., @GarthDanti
- Как использовать SPI на Arduino?
- Что выбрать между датчиками температуры и влажности: AM230x или DHT22?
- Подключение HX711 к трехпроводному датчику нагрузки
- Правильное использование * и & при передаче объектов в методах.
- ISO C++ запрещает принимать адрес неквалифицированной или заключенной в скобки нестатической функции-члена для формирования указателя на функцию-член
- Разница между массивом char и массивом unsigned char
- Печать содержимого файла SD - карты на ЖК-дисплее
- Отправка строки из RPi в Arduino - Рабочий код
сложность вашего кода была бы уменьшена, если бы вы использовали массивы для всех переменных, поскольку циклы можно было бы использовать для упрощения кода ...
Ткельвин[0]
, @jsotola