Помогите в допиливании кода
- Войдите на сайт для отправки комментариев
Вс, 27/04/2014 - 10:46
Собственно, написал код для считывания с 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); //Фаренгейты, один знак после запятой }
arssev1, в код не смотрел, скорее всего у вас типовуха - lcd не стирает экран без особой на то команды. Когда у вас меняются данные, они просто перезаписываются в те-же позиции. Используйте lcd.clear(), или если будет рябить, то нужно что-то придумывать, тема в принципе избитая, посмотрите кто как решает. Вот например обсуждали: http://arduino.ru/forum/programmirovanie/problema-s-vyvodom-znacheniya-p...
замени строки 154-161 на
Захотел сделать так, чтобы по нажатию кнопки менялось с Цельсиев на Фаренгейты и обратно, но что-то не выходит. При загрузке кода отображается на нижней строке температура в цельсиях, только число
зачем так сложно?
Тем более goto = флажок чайника :)
Ваш код работает следующим образом:
1.На верхней строке LCD по центру отображается надпись "ТЕМПЕРАТУРА:" (все ок)
2.Надпись стирается, на нижней строке в самом начале появляется значение температуры в Цельсиях (такого не должно по идее быть, то есть перед этим должна появится буква "Ц:"
3.при удержании кнопки отображаются фаренгейты тоже без буквы впереди тоже в начале строки
мне саечку: кроме теории надо тестировать на железе :) У тебя же дисплей 16х2, а я по привычке пишу для своего.
Кстати, в данной реализации кода чтения датчика температуры случайно выявлена фишка: если датчиков температуры подключено несколько, то их показания выводятся последовательно, безо всякого дополнительного кода. :) Надо это применить в своем проекте.
За что выражаю свое спасибо.
Я кажись понял в чем дело - подсчет lcd.setCursor работает немного иначе т.е максимальное значение в скобочках может быть (15,1) т.к. Подсчет с нуля
кроме теории надо тестировать на железе :)
После тестов обработал напильником (мб будет интересно):
А именно:
1.Вырезал буквы "Ц" и "Ф" ибо нафиг не нужны, т.к. в конце и так C или F
2.Понизил delay при чтении с кнопки
3.Исправил отображение на LCD (при условии того, что у меня 16x2)
4.Понизил delay в displayTemperature
Что обнаружил:
Появился противное мерцание экрана, немножко раздражает, пытался бороться с ним при помощи goto, программа зациклилась и не работала кнопка.
Как сделать так, чтобы 16 пробелов рисовались при смене с фаренгейтов на цельсии и наоборот, а не постоянно?
Строки 163-164 перенести на 70-ю строку.
Спасибо. А как с 2 датчиков читать?
Этот код и так читает со всех датчиков (подключать параллельно существующему), просто показания выводятся поочередно.
Согласно коду есть 2 переменные - 1 считается из показаний датчика (Цельсии), а вторая (Фаренгейты) считается из цельсиев по формуле. Куда будет записыватся температура из второго датчика если и в 1 и во второй переменной хранятся данные первого датчика?
P.S. Можешь дать какие-либо контакты, чтоб форум не засорять, что угодно (Skype, почту и т.д.) Буду признателен
В одну и ту же переменную пишутся. При первом проходе loop читается первый датчик и значения зано ятся в эти переменные. При втором прогоне цикла читается следующий датчик и в эту же переменную записываются его показания. Т.е. одновременно у тебя есть показания только одного из датчиков.
Чтобы использовать датчики одновременно, надо применять библиотеку DallasTemperature, там в примерах много чего есть, в том числе обращение по конкретному номеру или адресу датчика.
Какая жуткая реализация -_-
А как реализовать 2 датчика через DallasTemperature?
Это просто ваш код чтения датчика неклассический :)
Все, финиш, написал финальный код, все работает как надо, читает 2 датчика, кнопка работает, LCD не тупит, не мерцает
Кажись не набыдлокодил нигде