Не корректно отображает температуру
- Войдите на сайт для отправки комментариев
Собственно проблема в следующем - при использовании как аналогового (LM35) так и цифрового (DS18B20) датчика температуры симптомы одни и те же: Если подключить только датчк температуры, либо LM35 либо DS18B20, и использовать базовый скетч из примеров, то все в порядке - отображение температуры корректное, даже если немного усложнить кнопками или диодами тоже работает, но при использовани сдвигового регистра (74HC595) и соответственно библиотек (DallasTemperature.h, SPI.h) начинаются непонятки, тоесть температура датчика DS18B20 все время 0, а аналогового примерно 16 гр. и хоть грей хоть охлождай все равно не чего не меняется.
С бубном ходил, перечитал кучу форумов но ответа не нашел. Подскажите новичку!
Честно говоря не работал, c этим железом, но из общих соображений возникают такие вопросы:
1. Зачем? Для экономии ног? Так SPI сама-по себе позволяет подключать несколько ведомых устройст на одну линию. Или вы регистром пытаетесь выбирать "активное в данный момент" устройство?
2. Разве 74HC595 предназначен не для размножения выходов, а не входов?
3. Разве 74HC595 может работать с аналоговым сигналом?
Честно говоря не работал, c этим железом, но из общих соображений возникают такие вопросы:
1. Зачем? Для экономии ног? Так SPI сама-по себе позволяет подключать несколько ведомых устройст на одну линию. Или вы регистром пытаетесь выбирать "активное в данный момент" устройство?
2. Разве 74HC595 предназначен не для размножения выходов, а не входов?
3. Разве 74HC595 может работать с аналоговым сигналом?
Я наверное неправильно выразился, ибо SPI используется сугубо для датчика температуры (в будущем планируется несколько), аналоговый датчик естественно подсоеденен к отдельному аналоговому входу, а регистр используется действительно для увеличения выходов. Проблема в том что при использовании регистра (разумеется на отдельном выводе ардуино) вместе с каким либо датчиком показания последнего некорректны.
Если нужно могу привести пример промежуточного (тестового) варианта кода, сам работаю с системами вентиляции, кондиционирования, отопления... так вот при автоматизации онных часто приходится сталкиваться с решением задач автоматизации тех или иных механизмов, решения часто не тривиальны. Вот и решил, в качестве эксперимента попробовать реализовать простенькую схему автоматики не аппаратно а спомощью ардуино + увлекался когдато робототехникой сейчас появилось свободное время да и элементы стали гораздо доступнее.
Собственно отвлекся вот тестовый вариант, просьба с ходу не пинать он очень сырой.
#include <DallasTemperature.h> #include <SPI.h> /* Vcc ⇨ +5 В GND ⇨ GND QA-QH ⇨ светодиоды через резисторы на 200 Ом SI ⇨ пин 11 Arduino (MOSI) G ⇨ GND (выводы включены) RCK ⇨ пин 8 (SS) SCK ⇨ пин 13 (SCLK) SCLR ⇨ +5 В (сброс неактивен) QH' оставим неподключенным */ DallasTemperature tempSensor; // Инициализируем сенсор температуры enum { REG = 8 }; // К выводу ардуино // для хранения 16 битов используем unsigned int unsigned int bitsToSend = 0; // Подключения к выходам сдвигового регистра 74HC595 int regPinStatusLed = 0; // Пин регистра светодиодного индикатора int regPinMotorV = 1; // Пин регистра двигателя вытяжного вентилятора int regPinMotorP = 2; // Пин регистра двигателя приточного вентилятора int regPinServo = 3; // Пин регистра двигателя сервомотора int regPinHE1 = 6; // Пин регистра нагревательнах спиралей (heating elements) 1/3 int regPinHE2_3 = 7; // Пин регистра нагревательнах спиралей (heating elements) 2/3 // Переменные для управления системой char* vsStatus = "Stop"; // Состояние состемы float tempCurrent = 0; // Текущая температура int tempSet = 30; // Установленная температура int tempHE1 = 8; // Установленная температура int tempHE2_3 = 12; // Установленная температура // Подключение к ардуино напрямую int pinServoStatus = 5; // Состояние заслонки (открыта, закрыта) int pinHE_Alarm = 6; // Термостат перегрева тенов int pinTempSensor = 12; // Подключаем датчик типа DS18B20, DS18S20, DS1820 int pinButtonOn = 3; // Кнопка включить int pinButtonOff = 4; // Кнопка выключить int pinTempAnalog = A1; // Аналоговый датчик температуры void setup() { Serial.begin(9600); SPI.begin(); pinMode(REG, OUTPUT); // Гасим все ключи for (int i = 0; i < 16; i++) registerWrite(i, LOW); pinMode(pinServoStatus, INPUT); pinMode(pinHE_Alarm, INPUT); pinMode(pinTempSensor, INPUT); pinMode(pinButtonOn, INPUT); pinMode(pinButtonOff, INPUT); pinMode(pinTempAnalog, OUTPUT); tempSensor.begin(pinTempSensor); // Стартуем датчик температуры } // Функция открытия конкретного ключа на сдвиговом регистру void registerWrite(int whichPin, int whichState) { // выключаем светодиоды на время передачи битов digitalWrite(REG, LOW); // устанавливаем HIGH в соответствующий бит bitWrite(bitsToSend, whichPin, whichState); // Фокус вот в чём: сначала шлём старший байт SPI.transfer(highByte(bitsToSend)); // А потом младший SPI.transfer(lowByte(bitsToSend)); digitalWrite(REG, HIGH); } // Функция запуска вентиляционной установки void vsStart () { // Изменяем статус состояния состемы vsStatus = "Starting"; Serial.println ("The system starts ..."); // Зажигаем индикатор registerWrite (regPinStatusLed, HIGH); // Стартуем вытяжной вентилятор registerWrite (regPinMotorV, HIGH); Serial.println ("---> exhaust fan is running"); // Запускаем сервопривод для открытия заслонок registerWrite (regPinServo, HIGH); // Контролируем открытие заслонки, если заслонка закрыта ждем открытия Serial.println ("---> louvre shutter is opened ..."); while (digitalRead(pinServoStatus) == LOW) { registerWrite (regPinStatusLed, LOW); delay (500); registerWrite (regPinStatusLed, HIGH); delay (500); } Serial.println ("---> louvre shutter is open"); // Стартуем приточный вентилятор registerWrite (regPinMotorP, HIGH); Serial.println ("---> supply fan is running"); // Пауза для разгона приточного вентилятора 3 секунды delay (3000); // Изменяем статус состояния состемы Serial.println ("System is running"); vsStatus = "Start"; } void vsStop () { // Изменяем статус состояния состемы vsStatus = "Stoping"; Serial.println ("The system stops ..."); // Отключаем нагревательные элементы registerWrite (regPinHE1, LOW); registerWrite (regPinHE2_3, LOW); Serial.println ("---> turning off the heating elements"); // Если тены работали, делаем задержку для остывания спиралей Serial.println ("---> delay for cooling heating elements"); for (int i = 0; i < 10; i++) { registerWrite (regPinStatusLed, LOW); delay (500); registerWrite (regPinStatusLed, HIGH); delay (500); } // Выключаем приточный и вытяжной вентиляторы registerWrite (regPinMotorV, LOW); Serial.println ("---> turn off exhaust fans"); registerWrite (regPinMotorP, LOW); Serial.println ("---> turn off the supply air fan"); // Отключаем сервопривод для закрывания заслонки registerWrite (regPinServo, LOW); Serial.println ("---> turning off the servo valve to close"); // Гасим индикатор registerWrite (regPinStatusLed, LOW); // Изменяем статус состояния состемы Serial.println ("System halted"); vsStatus = "Stop"; } void heatersControl (float tempCurren) { // Вычисляем дельту между текущей температурой и заданной float tempDelta = tempSet - tempCurren; // Определяем какие из ступеней необходимо включать if (tempDelta > 0 && tempDelta <= tempHE1) { registerWrite (regPinHE1, HIGH); registerWrite (regPinHE2_3, LOW); } else if (tempDelta >= tempHE1 && tempDelta <= tempHE2_3) { registerWrite (regPinHE1, LOW); registerWrite (regPinHE2_3, HIGH); } else if (tempDelta >= tempHE2_3) { registerWrite (regPinHE1, HIGH); registerWrite (regPinHE2_3, HIGH); } else { registerWrite (regPinHE1, LOW); registerWrite (regPinHE2_3, LOW); } } void loop(void) { // Реакция на нажатие кнопки "Старт" if (digitalRead(pinButtonOn) == HIGH && vsStatus == "Stop") vsStart (); // Реакция на нажатие кнопки "Стоп" if (digitalRead(pinButtonOff) == HIGH && vsStatus == "Start") vsStop (); /* // Сканируем датчик температупы и вычисляем температуру float tempC = tempSensor.getTemperature(); Serial.print (tempC); Serial.println (" C"); */ float tempC = (5.0 * analogRead(pinTempAnalog) * 100.0) / 1024.0; Serial.print(tempC); Serial.println(" C"); delay (1000); // Запускаем контроль тенов if (digitalRead(pinHE_Alarm) == HIGH && vsStatus == "Start") heatersControl(tempC); // Сканируем состояние датчиков на предмет аварий // Проверяем нет ли перегрева, если да ждем остывания if (digitalRead(pinHE_Alarm) == LOW) { // Изменяем статус состояния состемы vsStatus = "Alarm!!!"; Serial.println ("Alarm!!! overheating of the heating elements"); // Отключаем нагревательные элементы registerWrite (regPinHE1, LOW); registerWrite (regPinHE2_3, LOW); Serial.println ("---> turning off the heating elements"); // Ждем остывания аварийного термостата while (digitalRead(pinHE_Alarm) == LOW) { registerWrite (regPinStatusLed, LOW); delay (300); registerWrite (regPinStatusLed, HIGH); delay (300); } // Пауза после остывания, на всякий случай for (int i = 0; i < 5; i++) { registerWrite (regPinStatusLed, LOW); delay (300); registerWrite (regPinStatusLed, HIGH); delay (300); } Serial.println ("---> heating elements are cooled"); Serial.println ("System in normal state"); // Изменяем статус состояния состемы vsStatus = "Start"; } // Не санкционированное закрытие заслонки if (digitalRead(pinServoStatus) == LOW && vsStatus == "Start") vsStop (); }Ну не вчитываясь в код, первое что бросается в глаза pinMode(pinTempAnalog, OUTPUT);
Ну не вчитываясь в код, первое что бросается в глаза pinMode(pinTempAnalog, OUTPUT);
Да это косяк, но суть не в этом. Моего вопроса это не решает.