Помогите в допиливании кода

arssev1
Offline
Зарегистрирован: 10.04.2014

Собственно, написал код для считывания с DS18x20 температуры, и вывод на LCD, в комнате все выводится нормально, но стоит температуре понизится, до однозначного числа, как сразу на LCD отображается не один знак после запятой, а 2, как это исправить. Конструктивная критика по коду приветствуется, комментраии в наличии

#include <LiquidCrystal.h> //Библиотека для работы с LCD
#include <OneWire.h> //Библиотека для работы по 1wire

byte letterP[8] =
{
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B00000,
}; //Добавляем букву "П"

byte letterU[8] =
{
  B10001,
  B10001,
  B10001,
  B01110,
  B00100,
  B01000,
  B10000,
  B00000,
}; //Добавляем букву "У"

byte letterC[8] =
{
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B11110,
  B00001,
  B00000,
}; //Добавляем букву "Ц"

byte letterF[8] =
{
  B00100,
  B01110,
  B10101,
  B10101,
  B10101,
  B01110,
  B00100,
  B00000,
}; //Добавляем букву "Ф"

OneWire  ds(8);  // Подключаем датчик к 8 цифровому пину

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Подключаем LCD


void setup(void) 
{
  Serial.begin(9600);// Связь с ПК
  lcd.createChar(1, letterP);
  lcd.createChar(2, letterU);
  lcd.createChar(3, letterC);
  lcd.createChar(4, letterF);
  lcd.begin(16, 2); //16 знаков, 2 строки
  lcd.setCursor(2, 0); //Отступ на 2 знака, на 3 пишем
  lcd.print("TEM""\1""EPAT""\2""PA:"); //Печатаем верхнюю строку LCD, слово "TEMПЕРАТУРА"
}

void loop(void) 
{
  byte i;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit; //Создаем паременные под Цельсии и Фаренгейты
  
  // Ищем алрес датчика
  if ( !ds.search(addr)) 
  {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  // Проверяем не было ли помех при передаче
  if (OneWire::crc8(addr, 7) != addr[7]) 
  {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // Определяем серию датчика
  switch (addr[0]) 
  {
    case 0x10:
      Serial.println("  Chip = DS18S20"); 
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();            
  ds.select(addr);       // Выбираем адрес
  ds.write(0x44, 1);     // Производим замер, в режиме паразитного питания
  delay(1000);    
  
  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Считываем оперативную память датчика

  for ( i = 0; i < 9; i++) 
  {           
    data[i] = ds.read(); // Заполняем массив считанными данными
  }  // Данные о температуре содержатся в первых двух байтах, переведем их в одно значение и преобразуем в шестнадцатиразрядное число
  int16_t raw = (data[1] << 8) | data[0]; // Переводим температуру в шкалы по Цельсию и Фаренгейту  
  if (type_s) 
  {
    raw = raw << 3; 
  }
  if (data[7] == 0x10) 
  {
    raw = (raw & 0xFFF0) + 12 - data[6];
  } else {
    byte cfg =  (data[4] & 0x60);
    if (cfg == 0x00) 
      raw = raw << 3; 
    else if  (cfg == 0x20) 
      raw = raw << 2; 
    else if  (cfg == 0x40) \
      raw = raw << 1;
  }  
  celsius =  (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0; 
  
  Serial.print("Temp = "); //Пишем в ПК информацию (на всякий случай)
  Serial.print(celsius);
  Serial.print(" C, ");
  Serial.print(fahrenheit);
  Serial.println(" F");
  
  lcd.setCursor(0, 1); //Пишем в LCD на 2 строке
  lcd.print("\3"":"); //Буква "Ц"
  lcd.setCursor(2, 1); //Отступ
  lcd.print(celsius, 1); //Цельсии, один знак после запятой
  lcd.setCursor(10, 1); //Отступ
  lcd.print("\4"":"); //Буква "Ф"
  lcd.setCursor(12, 1); //Отступ
  lcd.print(fahrenheit, 1); //Фаренгейты, один знак после запятой
 }

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

arssev1, в код не смотрел, скорее всего у вас типовуха - lcd не стирает экран без особой на то команды. Когда у вас меняются данные, они просто перезаписываются в те-же позиции. Используйте lcd.clear(), или если будет рябить, то нужно что-то придумывать, тема в принципе избитая, посмотрите кто как решает. Вот например обсуждали: http://arduino.ru/forum/programmirovanie/problema-s-vyvodom-znacheniya-p...

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

замени строки 154-161 на

lcd.setCursor(0, 1); //Пишем в LCD в ячейку с координатами x,y (отсчет с 0)
lcd.print("\3"":"); //Буква "Ц"
lcd.setCursor(2, 1); //Пишем в LCD в 3-ю позицию на 2-й строке
lcd.print("     "); //Убираем предыдущие показания (5 пробелов)
if (celsius > 0) lcd.print("+"); // чтобы положительные и отрицательные показания смотрелись одинаково
lcd.setCursor(2, 1); //Снова пишем в LCD в 3-ю позицию на 2-й строке
lcd.print(celsius, 1); //Цельсии, один знак после запятой

lcd.setCursor(10, 1); //Пишем в LCD в 11-ю позицию на 2-й строке
lcd.print("\4"":"); //Буква "Ф"
lcd.setCursor(13, 1); //Пишем в LCD в 14-ю позицию на 2-й строке
lcd.print("     "); //Убираем предыдущие показания (5 пробелов)
if (fahrenheit > 0) lcd.print("+"); // плюсик для красоты
lcd.setCursor(13, 1); //Снова пишем в LCD в 14-ю позицию на 2-й строке
lcd.print(fahrenheit, 1); //Фаренгейты, один знак после запятой

 

 

 

arssev1
Offline
Зарегистрирован: 10.04.2014

Захотел сделать так, чтобы по нажатию кнопки менялось с Цельсиев на Фаренгейты и обратно, но что-то не выходит. При загрузке кода отображается на нижней строке температура в цельсиях, только число

#include <LiquidCrystal.h> //Библиотека для работы с LCD
#include <OneWire.h> //Библиотека для работы по 1wire

byte letterP[8] =
{
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B00000,
}; //Добавляем букву "П"

byte letterU[8] =
{
  B10001,
  B10001,
  B10001,
  B01110,
  B00100,
  B01000,
  B10000,
  B00000,
}; //Добавляем букву "У"

byte letterC[8] =
{
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B11110,
  B00001,
  B00000,
}; //Добавляем букву "Ц"

byte letterF[8] =
{
  B00100,
  B01110,
  B10101,
  B10101,
  B10101,
  B01110,
  B00100,
  B00000,
}; //Добавляем букву "Ф"

OneWire  ds(8);  // Подключаем датчик к 8 цифровому пину

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Подключаем LCD

const int buttonPin = 9;

float celsius, fahrenheit; //Создаем паременные под Цельсии и Фаренгейты

int val = 0;

void setup(void) 
{
  Serial.begin(9600);// Связь с ПК
  lcd.createChar(1, letterP);
  lcd.createChar(2, letterU);
  lcd.createChar(3, letterC);
  lcd.createChar(4, letterF);
  lcd.begin(16, 2); //16 знаков, 2 строки
  lcd.setCursor(2, 0); //Отступ на 2 знака, на 3 пишем
  lcd.print("TEM""\1""EPAT""\2""PA:"); //Печатаем верхнюю строку LCD, слово "TEMПЕРАТУРА"
}

void loop(void) 
{
  byte i;
  byte type_s;
  byte data[12];
  byte addr[8];
  
  // Ищем алрес датчика
  if ( !ds.search(addr)) 
  {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  // Проверяем не было ли помех при передаче
  if (OneWire::crc8(addr, 7) != addr[7]) 
  {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // Определяем серию датчика
  switch (addr[0]) 
  {
    case 0x10:
      Serial.println("  Chip = DS18S20"); 
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();            
  ds.select(addr);       // Выбираем адрес
  ds.write(0x44, 1);     // Производим замер, в режиме паразитного питания
  delay(1000);    
  
  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Считываем оперативную память датчика

  for ( i = 0; i < 9; i++) 
  {           
    data[i] = ds.read(); // Заполняем массив считанными данными
  }  // Данные о температуре содержатся в первых двух байтах, переведем их в одно значение и преобразуем в шестнадцатиразрядное число
  int16_t raw = (data[1] << 8) | data[0]; // Переводим температуру в шкалы по Цельсию и Фаренгейту  
  if (type_s) 
  {
    raw = raw << 3; 
  }
  if (data[7] == 0x10) 
  {
    raw = (raw & 0xFFF0) + 12 - data[6];
  } else {
    byte cfg =  (data[4] & 0x60);
    if (cfg == 0x00) 
      raw = raw << 3; 
    else if  (cfg == 0x20) 
      raw = raw << 2; 
    else if  (cfg == 0x40) \
      raw = raw << 1;
  }  
  celsius =  (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0; 
  
  Serial.print("Temp = "); //Пишем в ПК информацию (на всякий случай)
  Serial.print(celsius);
  Serial.print(" C, ");
  Serial.print(fahrenheit);
  Serial.println(" F");
  
   if (digitalRead(buttonPin) == HIGH)
 {
  val = (val + 1);
  delay(500);
 }

if(val == 2)
 {
  val = 0;
 }
if(val == 0)
 {
  displayC(); 
 }
if(val == 1)
 {
  displayF();
 }
 }
 
void displayF()
{
 lcd.setCursor(0,1);
 lcd.print("                ");
 label:
 lcd.setCursor(0,4);
 lcd.print("\4"":");
 lcd.setCursor(0,6);
 lcd.print(fahrenheit, 1);
 delay(100);
 goto label;
 }
void displayC()
{
 lcd.setCursor(0,1);
 lcd.print("                ");
 label:
 lcd.setCursor(0,4);
 lcd.print("\3"":");
 lcd.setCursor(0,6);
 lcd.print(celsius, 1);
 delay(100);
 goto label;
 }
 

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

зачем так сложно?
Тем более goto = флажок чайника :)

#include <LiquidCrystal.h> //Библиотека для работы с LCD
#include <OneWire.h> //Библиотека для работы по 1wire

#define PIN_ONEWIRE 8  // пин для датчиков температуры
#define PIN_BUTTON 9   // пин для кнопки

boolean displayCelsius = true;  // логическая переменная, если false, то отображаем по Фаренгейту

byte letterP[8] =
{
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B00000,
}; //Добавляем букву "П"

byte letterU[8] =
{
  B10001,
  B10001,
  B10001,
  B01110,
  B00100,
  B01000,
  B10000,
  B00000,
}; //Добавляем букву "У"

byte letterC[8] =
{
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B11110,
  B00001,
  B00000,
}; //Добавляем букву "Ц"

byte letterF[8] =
{
  B00100,
  B01110,
  B10101,
  B10101,
  B10101,
  B01110,
  B00100,
  B00000,
}; //Добавляем букву "Ф"

byte gradus[8] =
{
0xc,0x12,0x12,0xc,0x0,0x0,0x0,0x0
}; //Добавляем символ градуса

OneWire  ds(PIN_ONEWIRE);  // Подключаем датчик к 8 цифровому пину

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Подключаем LCD

float celsius, fahrenheit; //Создаем паременные под Цельсии и Фаренгейты


void setup(void) 
{
  Serial.begin(9600);// Связь с ПК
  lcd.createChar(1, letterP);
  lcd.createChar(2, letterU);
  lcd.createChar(3, letterC);
  lcd.createChar(4, letterF);
  lcd.createChar(5, gradus);
  lcd.begin(16, 2); //16 знаков, 2 строки
  lcd.setCursor(2, 0); //Отступ на 2 знака, на 3 пишем
  lcd.print("TEM""\1""EPAT""\2""PA:"); //Печатаем верхнюю строку LCD, слово "TEMПЕРАТУРА"
}


void loop()
{
  readSensor();
  checkButton();
  displayTemperature();
}


void checkButton()
{
  if (digitalRead(PIN_BUTTON) == HIGH) // если нажата кнопка, 
  {
    displayCelsius = !displayCelsius;  // то инвертируем логическую переменную
    delay(500);                        // защита от дребезга
  }
}


void readSensor()
{  
  byte i;
  byte type_s;
  byte data[12];
  byte addr[8];

  // Ищем алрес датчика
  if ( !ds.search(addr)) 
  {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  // Проверяем не было ли помех при передаче
  if (OneWire::crc8(addr, 7) != addr[7]) 
  {
    Serial.println("CRC is not valid!");
    return;
  }
  Serial.println();

  // Определяем серию датчика
  switch (addr[0]) 
  {
  case 0x10:
    Serial.println("  Chip = DS18S20"); 
    type_s = 1;
    break;
  case 0x28:
    Serial.println("  Chip = DS18B20");
    type_s = 0;
    break;
  case 0x22:
    Serial.println("  Chip = DS1822");
    type_s = 0;
    break;
  default:
    Serial.println("Device is not a DS18x20 family device.");
    return;
  } 

  ds.reset();            
  ds.select(addr);       // Выбираем адрес
  ds.write(0x44, 1);     // Производим замер, в режиме паразитного питания
  delay(1000);    

  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Считываем оперативную память датчика

  for ( i = 0; i < 9; i++) 
  {           
    data[i] = ds.read(); // Заполняем массив считанными данными
  }  // Данные о температуре содержатся в первых двух байтах, переведем их в одно значение и преобразуем в шестнадцатиразрядное число
  int16_t raw = (data[1] << 8) | data[0]; // Переводим температуру в шкалы по Цельсию и Фаренгейту  
  if (type_s) 
  {
    raw = raw << 3; 
  }
  if (data[7] == 0x10) 
  {
    raw = (raw & 0xFFF0) + 12 - data[6];
  } 
  else {
    byte cfg =  (data[4] & 0x60);
    if (cfg == 0x00) 
      raw = raw << 3; 
    else if  (cfg == 0x20) 
      raw = raw << 2; 
    else if  (cfg == 0x40) \
      raw = raw << 1;
  }  
  celsius =  (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0; 

  Serial.print("Temp = "); //Пишем в ПК информацию (на всякий случай)
  Serial.print(celsius);
  Serial.print(" C, ");
  Serial.print(fahrenheit);
  Serial.println(" F");
}

void displayTemperature()
{
  lcd.setCursor(0,0);
  lcd.print("                ");
  
  lcd.setCursor(0,4);
  // если переменная displayCelsius сейчас true, то выводим по Цельсию
  if (displayCelsius) {lcd.print("\4"":");}  
  else {lcd.print("\3"":");}
  
  lcd.setCursor(0,6);
  if ((celsius > 0) || (fahrenheit > 0)) lcd.print("+");
  
  lcd.print(displayCelsius?celsius:fahrenheit, 1);
  // равноценно выражению:
  // if (displayCelsius == true) lcd.print(celsius, 1); 
  // else lcd.print(fahrenheit, 1);
  
  lcd.print("\5");  //значок градуса
  lcd.print(displayCelsius?"C":"F"); 
  
  delay(1000);      // меньше нет смысла, т.к. датчик выдает показания не чаще раз в 750 мс
}


 

arssev1
Offline
Зарегистрирован: 10.04.2014

Ваш код работает следующим образом: 

1.На верхней строке LCD по центру отображается надпись "ТЕМПЕРАТУРА:" (все ок)

2.Надпись стирается, на нижней строке в самом начале появляется значение температуры в Цельсиях (такого не должно по идее быть, то есть перед этим должна появится буква "Ц:"

3.при удержании кнопки  отображаются фаренгейты  тоже без буквы впереди тоже в начале строки

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

мне саечку: кроме теории надо тестировать на железе :) У тебя же дисплей 16х2, а я по привычке пишу для своего.

void displayTemperature()
{
  lcd.setCursor(0,2);
  lcd.print("                ");
  
  lcd.setCursor(0,2);
  // если переменная displayCelsius сейчас true, то выводим по Цельсию
  if (displayCelsius) {lcd.print("\3"":");}  
  else {lcd.print("\4"":");}
  
  lcd.setCursor(2,2);
  if ((celsius > 0) || (fahrenheit > 0)) lcd.print("+");
  
  lcd.print(displayCelsius?celsius:fahrenheit, 1);
  // равноценно выражению:
  // if (displayCelsius == true) lcd.print(celsius, 1); 
  // else lcd.print(fahrenheit, 1);
  
  lcd.print("\5");  //значок градуса
  lcd.print(displayCelsius?"C":"F"); 
  
  delay(100);
}

Кстати, в данной реализации кода чтения датчика температуры случайно выявлена фишка: если датчиков температуры подключено несколько, то их показания выводятся последовательно, безо всякого дополнительного кода. :) Надо это применить в своем проекте.
За что выражаю свое спасибо.

arssev1
Offline
Зарегистрирован: 10.04.2014

Я кажись понял в чем дело - подсчет lcd.setCursor работает немного иначе т.е максимальное значение в скобочках может быть (15,1) т.к. Подсчет с нуля

arssev1
Offline
Зарегистрирован: 10.04.2014

Tomasina пишет:

 кроме теории надо тестировать на железе :) 

После тестов обработал напильником (мб будет интересно):

#include <LiquidCrystal.h> //Библиотека для работы с LCD
#include <OneWire.h> //Библиотека для работы по 1wire

#define PIN_ONEWIRE 8  // пин для датчиков температуры
#define PIN_BUTTON 9   // пин для кнопки

boolean displayCelsius = true;  // логическая переменная, если false, то отображаем по Фаренгейту

byte letterP[8] =
{
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B00000,
}; //Добавляем букву "П"

byte letterU[8] =
{
  B10001,
  B10001,
  B10001,
  B01110,
  B00100,
  B01000,
  B10000,
  B00000,
}; //Добавляем букву "У"

byte gradus[8] =
{
0xc,0x12,0x12,0xc,0x0,0x0,0x0,0x0
}; //Добавляем символ градуса

OneWire  ds(PIN_ONEWIRE);  // Подключаем датчик к 8 цифровому пину

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Подключаем LCD

float celsius, fahrenheit; //Создаем паременные под Цельсии и Фаренгейты


void setup(void) 
{
  Serial.begin(9600);// Связь с ПК
  lcd.createChar(1, letterP);
  lcd.createChar(2, letterU);
  lcd.createChar(3, gradus);
  lcd.begin(16, 2); //16 знаков, 2 строки
  lcd.setCursor(2, 0); //Отступ на 2 знака, на 3 пишем
  lcd.print("TEM""\1""EPAT""\2""PA:"); //Печатаем верхнюю строку LCD, слово "TEMПЕРАТУРА"
}


void loop()
{
  readSensor();
  checkButton();
  displayTemperature();
}


void checkButton()
{
  if (digitalRead(PIN_BUTTON) == HIGH) // если нажата кнопка, 
  {
    displayCelsius = !displayCelsius;  // то инвертируем логическую переменную
    delay(100);                        // защита от дребезга
  }
}


void readSensor()
{  
  byte i;
  byte type_s;
  byte data[12];
  byte addr[8];

  // Ищем алрес датчика
  if ( !ds.search(addr)) 
  {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  // Проверяем не было ли помех при передаче
  if (OneWire::crc8(addr, 7) != addr[7]) 
  {
    Serial.println("CRC is not valid!");
    return;
  }
  Serial.println();

  // Определяем серию датчика
  switch (addr[0]) 
  {
  case 0x10:
    Serial.println("  Chip = DS18S20"); 
    type_s = 1;
    break;
  case 0x28:
    Serial.println("  Chip = DS18B20");
    type_s = 0;
    break;
  case 0x22:
    Serial.println("  Chip = DS1822");
    type_s = 0;
    break;
  default:
    Serial.println("Device is not a DS18x20 family device.");
    return;
  } 

  ds.reset();            
  ds.select(addr);       // Выбираем адрес
  ds.write(0x44, 1);     // Производим замер, в режиме паразитного питания
  delay(1000);    

  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Считываем оперативную память датчика

  for ( i = 0; i < 9; i++) 
  {           
    data[i] = ds.read(); // Заполняем массив считанными данными
  }  // Данные о температуре содержатся в первых двух байтах, переведем их в одно значение и преобразуем в шестнадцатиразрядное число
  int16_t raw = (data[1] << 8) | data[0]; // Переводим температуру в шкалы по Цельсию и Фаренгейту  
  if (type_s) 
  {
    raw = raw << 3; 
  }
  if (data[7] == 0x10) 
  {
    raw = (raw & 0xFFF0) + 12 - data[6];
  } 
  else {
    byte cfg =  (data[4] & 0x60);
    if (cfg == 0x00) 
      raw = raw << 3; 
    else if  (cfg == 0x20) 
      raw = raw << 2; 
    else if  (cfg == 0x40) \
      raw = raw << 1;
  }  
  celsius =  (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0; 

  Serial.print("Temp = "); //Пишем в ПК информацию (на всякий случай)
  Serial.print(celsius);
  Serial.print(" C, ");
  Serial.print(fahrenheit);
  Serial.println(" F");
}

void displayTemperature()
{
  lcd.setCursor(0,1);
  lcd.print("                ");
  lcd.setCursor(4,1);
  if ((celsius > 0) || (fahrenheit > 0)) lcd.print("+");
  
  lcd.print(displayCelsius?celsius:fahrenheit, 1);
  // равноценно выражению:
  // if (displayCelsius == true) lcd.print(celsius, 1); 
  // else lcd.print(fahrenheit, 1);
  
  lcd.print("\3");  //значок градуса
  lcd.print(displayCelsius?"C":"F"); 
  delay(750);
}

А именно:

1.Вырезал буквы "Ц" и "Ф" ибо нафиг не нужны, т.к. в конце и так C или F

2.Понизил delay при чтении с кнопки

3.Исправил отображение на LCD (при условии того, что у меня 16x2)

4.Понизил delay в displayTemperature 

Что обнаружил:

Появился противное мерцание экрана, немножко раздражает, пытался бороться с ним при помощи goto, программа зациклилась и не работала кнопка.

Как сделать так, чтобы 16 пробелов рисовались при смене с фаренгейтов на цельсии и наоборот, а не постоянно?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Строки 163-164 перенести на 70-ю строку.

arssev1
Offline
Зарегистрирован: 10.04.2014

Спасибо. А как с 2 датчиков читать?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Этот код и так читает со всех датчиков (подключать параллельно существующему), просто показания выводятся поочередно.

arssev1
Offline
Зарегистрирован: 10.04.2014

Согласно коду есть 2 переменные - 1 считается из показаний датчика (Цельсии), а вторая (Фаренгейты) считается из цельсиев по формуле. Куда будет записыватся температура из второго датчика если и в 1 и во второй переменной хранятся данные первого датчика?

P.S. Можешь дать какие-либо контакты, чтоб форум не засорять, что угодно (Skype, почту и т.д.) Буду признателен

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

В одну и ту же переменную пишутся. При первом проходе loop читается первый датчик и значения зано ятся в эти переменные. При втором прогоне цикла читается следующий датчик и в эту же переменную записываются его показания. Т.е. одновременно у тебя есть показания только одного из датчиков.
Чтобы использовать датчики одновременно, надо применять библиотеку DallasTemperature, там в примерах много чего есть, в том числе обращение по конкретному номеру или адресу датчика.

arssev1
Offline
Зарегистрирован: 10.04.2014

Какая жуткая реализация -_-

А как реализовать 2 датчика через DallasTemperature?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Это просто ваш код чтения датчика неклассический :)

arssev1
Offline
Зарегистрирован: 10.04.2014

Все, финиш, написал финальный код, все работает как надо, читает 2 датчика, кнопка работает, LCD не тупит, не мерцает

#include <LiquidCrystal.h> //Библиотека для работы с LCD
#include <OneWire.h> //Библиотека для работы по 1wire
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 8
#define PIN_BUTTON 9   // пин для кнопки

boolean displayCelsius = true;  // логическая переменная, если false, то отображаем по Фаренгейту

byte gradus[8] =
{
0xc,0x12,0x12,0xc,0x0,0x0,0x0,0x0
}; //Добавляем символ градуса

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Подключаем LCD

float celsius0, fahrenheit0, celsius1, fahrenheit1; //Создаем паременные под Цельсии и Фаренгейты


void setup(void) 
{
  sensors.begin();
  lcd.createChar(1, gradus);
  lcd.begin(16, 2); //16 знаков, 2 строки
  lcd.print("Inside   Outside"); //Печатаем верхнюю строку LCD, слово "TEMПЕРАТУРА"
}


void loop()
{
  readSensor();
  checkButton();
  displayTemperature();
}


void checkButton()
{
  if (digitalRead(PIN_BUTTON) == HIGH) // если нажата кнопка, 
  {
    lcd.setCursor(0,1);
    lcd.print("                ");
    displayCelsius = !displayCelsius;  // то инвертируем логическую переменную
    delay(100);                        // защита от дребезга
  }
}


void readSensor()
{  
  sensors.requestTemperatures();
  celsius0 = sensors.getTempCByIndex(0);
  celsius1 = sensors.getTempCByIndex(1);
  fahrenheit0 = celsius0 * 1.8 + 32.0;
  fahrenheit1 = celsius1 * 1.8 + 32.0;
}

void displayTemperature()
{
  lcd.setCursor(0,1);
  lcd.print(displayCelsius?celsius0:fahrenheit0, 1);
  lcd.print("\1");  //значок градуса
  lcd.print(displayCelsius?"C":"F"); 
  
  lcd.setCursor(10,1);
  lcd.print(displayCelsius?celsius1:fahrenheit1, 1);
  lcd.print("\1");  //значок градуса
  lcd.print(displayCelsius?"C":"F"); 
  
  delay(750);
}

Кажись не набыдлокодил нигде