Некорректные значения температуры в Proteus

m_i_g
Offline
Зарегистрирован: 19.04.2018

Собственно хочу сделать часы в машину с показометром температуры и бортового напряжения.

Пока не приехала плата ардуино делаю модель в Протеус.

Но на дисплее получаю либо нормальный температуру, либо -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");

  }
}

 

m_i_g
Offline
Зарегистрирован: 19.04.2018

И ещё, можно ли эти 3 строки:

    lcd.print("V=");
    lcd.print(vin,1);
    lcd.print("B");

 

записать одной строчкой?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

В свойствах вашего термодатчика в протеусе покрутите таймауты. В данный момент не помню какой именно, но помомему Time Reset Low уменьшал до 470, и Conversion Time сделайте поменьше. 

m_i_g
Offline
Зарегистрирован: 19.04.2018

Огромное спасибо. Помогло. А по второму вопросу?

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Ну вы даете :) 

Можно, разрешаю :)

lcd.print("V="); lcd.print(vin,1); lcd.print("B");

Для чего вы хотите это сделать ?

m_i_g
Offline
Зарегистрирован: 19.04.2018

Я имел ввиду одной командой lcd.print() сразу все три значения вывести. По аналогии с С++ когда выводимые значения через запятую в одном операторе идут.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Это и есть с++, возможно вы имели в виду что то типа sprintf, printf и иже с ними ? Так ответьте на вопрос "для чего" ? Чем вас не устраивает текущая конструкция ? Какова конечная цель ?

m_i_g
Offline
Зарегистрирован: 19.04.2018

Да, я именно это имел ввиду. 

Конструкция устраивает всем, кроме краткости записи. Но не принципиально. Спасибо.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Краткость записи в коде не означает малый объем откомпилированного кода.

m_i_g
Offline
Зарегистрирован: 19.04.2018

Это я знаю.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

m_i_g пишет:

И ещё, можно ли эти 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; }

а потом, где надо, пишите "как в С++"

lcd << "V=" << vin << "B";

Только указание на 1 знак после запятой потеряете. Если так важно, нужно будет ещё несколько строк в начале программы написать.