Некорректные значения температуры в Proteus
- Войдите на сайт для отправки комментариев
Чт, 19/04/2018 - 15:51
Собственно хочу сделать часы в машину с показометром температуры и бортового напряжения.
Пока не приехала плата ардуино делаю модель в Протеус.
Но на дисплее получаю либо нормальный температуру, либо -0.1*С
При это температура датчика не влияет на отображение -0.1
Это мой первый скетч и первая проба ардуино. Может я в коде где ошибся? Или протеус глючит?
p.s. прерывание дёргают раз в секунду часы реального времени
#include <Wire.h>
#include <OneWire.h>
#include <LiquidCrystal.h> //подключаем библиотеку
#include <iarduino_RTC.h> // подключаем библиотеку для работы с RTC модулем
OneWire ds(2); // Создаем объект OneWire для шины 1-Wire на 2 ноге контроллера
LiquidCrystal lcd(9, 8, 4, 5, 6, 7 );
iarduino_RTC time(RTC_DS1307); // объявляем переменную time для работы с библиотекой, указывая название модуля RTC_DS1307
byte simvol_1[8] = { // создаем символ градус цельсия и присваиваем ему имя "simvol_1"
0b01100,
0b10010,
0b10010,
0b01100,
0b00000,
0b00000,
0b00000,
0b00000
};
volatile boolean int_point = false; // флаг выполнения прерывания
byte analogInput = 0; // пин на котором измеряется напряжение
float vin = 0.0; // выводимое напряжение
int value = 0; // значение на входе контроллера
void StartMeasuringTemperature()
{
ds.reset(); // Начинаем взаимодействие со сброса всех предыдущих команд и параметров
ds.write(0xCC); // Даем датчику DS18b20 команду пропустить поиск по адресу. В нашем случае только одно устрйоство
ds.write(0x44); // Даем датчику DS18b20 команду измерить температуру. Само значение температуры мы еще не получаем - датчик его положит во внутреннюю память
}
void setup() // ---------------- ПЕРВОНАЧАЛЬНЫЕ УСТАНОВКИ -------------------
{
byte i;
pinMode(11,INPUT_PULLUP); // кнопка UP
pinMode(12,INPUT_PULLUP); // кнопка DOWN
pinMode(analogInput, INPUT); //
attachInterrupt(1, IntWork, RISING); // назначем функцию InWork на передний фронт на ноге D3
time.begin(); // инициируем RTC модуль
lcd.begin(16, 2); //Инициализируем дисплей: 2 строки по 16 символов
lcd.createChar(1, simvol_1);
lcd.setCursor(2, 0);
lcd.print("DAEWOO MATIZ");
StartMeasuringTemperature(); // Даем команду датчику температуры измерить температуру
delay(2000); // Ждем 2 секунды пока отображается заставка
lcd.setCursor(2, 0);
for (i = 0; i < 12; i++) // затираем заставку
{
lcd.print(" ");
delay(100);
}
}
void IntWork() // -------------- ОБРАБОТЧИК ПРЕРЫВАНИЯ --------------------
{
int_point = true; // если пришёл передний фронт - выставляем флаг, что произошло прерывание
}
void loop() // --------------------- ОСНОВНОЙ ЦИКЛ -------------------------
{
if (int_point) // если было прерывание (установлен флаг int_point) выполняем чтение данных и обновление дисплея
{
byte data[2]; // Место для значения температуры
int_point = false;
// Вычисляем температуру и выводим
ds.reset(); // Готовимся получить значение измеренной температуры
ds.write(0xCC); // Даем датчику DS18b20 команду пропустить поиск по адресу. В нашем случае только одно устрйоство
ds.write(0xBE); // Просим передать нам значение регистров со значением температуры
// Получаем и считываем ответ
data[0] = ds.read(); // Читаем младший байт значения температуры
data[1] = ds.read(); // А теперь старший
StartMeasuringTemperature(); // Даем команду датчику температуры измерить температуру
// Формируем итоговое значение:
// - сперва "склеиваем" значение,
// - затем умножаем его на коэффициент, соответсвующий разрешающей способности (для 12 бит по умолчанию - это 0,0625)
float temperature = ((data[1] << 8) | data[0]) * 0.0625;
lcd.setCursor(0, 1);
lcd.print(temperature,1);
lcd.print(char(1)); // печатаем символ градусов
lcd.print("C ");
// Читаем и выводим время
lcd.setCursor(4, 0);
lcd.print(time.gettime("H:i:s")); // выводим время
// Вычисляем напряжение и выводим
value = analogRead(analogInput); // читаем входное напряжение на A0
vin = (value * 0.005) / 0.17;
lcd.setCursor(9, 1);
lcd.print("V=");
lcd.print(vin,1);
lcd.print("B");
}
}
И ещё, можно ли эти 3 строки:
lcd.print("V="); lcd.print(vin,1); lcd.print("B");записать одной строчкой?
В свойствах вашего термодатчика в протеусе покрутите таймауты. В данный момент не помню какой именно, но помомему Time Reset Low уменьшал до 470, и Conversion Time сделайте поменьше.
Огромное спасибо. Помогло. А по второму вопросу?
Ну вы даете :)
Можно, разрешаю :)
lcd.print("V="); lcd.print(vin,1); lcd.print("B");Для чего вы хотите это сделать ?
Я имел ввиду одной командой lcd.print() сразу все три значения вывести. По аналогии с С++ когда выводимые значения через запятую в одном операторе идут.
Это и есть с++, возможно вы имели в виду что то типа sprintf, printf и иже с ними ? Так ответьте на вопрос "для чего" ? Чем вас не устраивает текущая конструкция ? Какова конечная цель ?
Да, я именно это имел ввиду.
Конструкция устраивает всем, кроме краткости записи. Но не принципиально. Спасибо.
Краткость записи в коде не означает малый объем откомпилированного кода.
Это я знаю.
И ещё, можно ли эти 3 строки:
lcd.print("V="); lcd.print(vin,1); lcd.print("B");записать одной строчкой?
В начало программы вставьте строку
template <typename T> inline Print & operator << (Print &s, T n) { s.print(n); return s; }а потом, где надо, пишите "как в С++"
Только указание на 1 знак после запятой потеряете. Если так важно, нужно будет ещё несколько строк в начале программы написать.