А как управлять RGB светодиодом при помощи датчика температуры? То есть менять цвета от зависимости температуры.
- Войдите на сайт для отправки комментариев
Втр, 08/04/2014 - 08:21
Подскажите как управлять RGB светодиодом при помощи датчика температуры? То есть менять цвета от зависимости температуры.
сначала сделать три канала с силовыми ключами управляемые с аналоговых выходов (PWM). Затем сделать замер температуры и последним шагом настроить формулу или таблицу связи температуры с тремя числами от 0 до 255 - значениями яркости каждого из каналов RGB
сначала сделать три канала с силовыми ключами управляемые с аналоговых выходов (PWM). Затем сделать замер температуры и последним шагом настроить формулу или таблицу связи температуры с тремя числами от 0 до 255 - значениями яркости каждого из каналов RGB
А я думаю, это нужно делать в таком порядке:
1. Подключить датчик температуры. И на базовых примерах научится с ним работать (получать температуру, отправлять в Serial, зажигать встроенный светодиод при достижении определенной температуры).
2. Отложить в сторону предыдущий скетч и датчик, взять обычный светик (или опять-таки встроенный) и научится управлять его яркостью.
3. Добавить еще два светка, и научится "рулить яркостью" стразу троих, для начала выставлять их в какие-то предопределенные значения.
4. Выкинуть два светика, и научится менять яркость одного в зависимости от температуры. Вначале линейно (чем выше температура - тем ярче светик)
5. То же самое, но зависимость уже не линейная, а по какой-то "формуле" (экспонента, по квадратичному закону и т.п.) или по "табличным значениям".
6. То же самое, но уже для трех светиков. Но табличка связей "температру-яркость" - для каждого светодиода своя.
7. Смотрим на свой RGB светодиод. Если каждый его канал ждерт больше 40-ма, то делаем развязку силовыми ключами или ULN-кой (вообщем гуглим "ардуина управление мощьной нагрузкой"). Если <=40ma, то пропускаем этот пункт
8. Заменяем три светика на свой RGB диод.
9. Радуемся.
В процессе всех этих разбирательств, не нужно пытатся найти пример "вот в точности такой как у меня". Скажем "научится менять яркость одного в зависимости от температуры". В точности такого примера можно и не найти. Зато можно найти пример, где яркость меняют в зависимости от положения аналогового резистора (кстати этот пример - тоже можно попрбовать). Разобратся с ним, и потом заменить в нем "чтение аналогового входа", на "чтение температуры со своего датчика" (к этому моменту вы уже должны уметь это, если шли по пунктам).
То же самое с "менять по табличному значению". Примера "температура-яркость" - может и не быть. Но может быть пример "температура --> угло сервы". Или "аналоговый вход -->угол сервы".
Точно так же с "силовыми развязками". Смотрим все примеры где ардуина рулит "чем-то мощьным". Разбираемся по каким принципам это делается...
P.S. На самом деле, я не сказал что-то "противоположное" тому что предолжил axill. Иток - тот же самый. Я дал просто "разбивку" как прийти к этому итогу. Разрезал слона на куссочки которые легче прожевать.
leshak полностью поддерживаю) у меня просто столько буков не нашлось)
leshak полностью поддерживаю) у меня просто столько буков не нашлось)
Ну тогда можно было проще: начните с blink и ПОСТЕПЕННО превращайте его в блекдежк со шлюхами ;)
А вообще меня всегда умиляют попытки построить сразу "вот что-то этакое" (хотя, в данном случае, нужно признать размер "хотелок" довольно скромен и близок к здравому смыслу). Иногда встречаются "я хочу сделать автопилот для боинга, только в програмировании слаб. помогите новичку" :)
Я, с 10-ти летним опытом программинга, и то не возмусь писать что-то больше 10-ти строк "сразу целиком". Только что-то минимальное, и постепенно усложнять. Опять-таки "минимальными шагами". Добавляя только "что-то одно за раз".
Опять согласен) я сам два года газад загорелся идеей сделать свой контроллер приточной вентиляции, чтобы интегрировать его с умным домом. Не самая простая задача чтобы с нее начинать) однако постепенно шаг за шагом я уже очень близок к тому, чтобы сделать ее в один присест. За это время много чего освоил, и про пайку вспомнил и про програмирование и сделал работающие устройства интегрированные с умным домом. В общем большая цель сама по себе это не плохо. Но достичь ее сходу - не разумно. А во. Держа в голове большую цель подбираться к ней шаг за шагом - самое то
Полностью солидарен. Я сам по сути новичёк и не программист, но шаг за шагом, по пути читая и вникая в новые для меня темы, получается сделать какие то работающие устройства. Приходится тратить время, задавать вопросы на форуме, но если это интересно и хочется получить результат, то это единственный ПРАВИЛЬНЫЙ подход.
Респект участникам данного форума. Приглашаю единомышленникам объединить усилия в разрезании и поедании слона.
Моя задумка - отображение определенного (задаваемого) диапазона температуры с помощью спектра свечения RGB LED. Сама температура отражается на LCD дисплее, кнопками либо энкодером задаем диапазон температур, подлежащий контролю путем изменения спектра свечения RGB LED.
Применение, например, подсветека парной в бане плавно изменяет свой цвет от холодного - синего до горячего - красного в зависимости от температуры в диапазоне 70-120 градусов. Или светильник изменяет свой цвет зимой в диапазоне от -30(холодно) до -10(жарко). Летом задаем диапазон от +20 до +35, визуальный контроль за температурой в парнике (красиво подсвеченная теплица на участке, чем ни проект?)
Большое отдельное спасибо участнику Leshak за систематизацию задачи.
Для начала, хочу предложить к обсуждению проект приведенный в ссылке http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED
правда, не все мне здесь нравится, и именно, использование самого RGB LED модуля.
Что касается управления мощными нагрузками, эта задача уже решена многократно. Наример http://habrahabr.ru/post/224621/ или http://cxem.net/beginner/beginner61.php
Но давайте пойдем шаг за шагом, как завещал великий Leshak.
Жду идей и предложений, и сам готов по мере возможности публиковать свои наработки.
используйте функцию map - сам сегодня о ней узнал, очень нужнаю.
примерно так можно реализовать
1
int
red=map(значение температуры, -30, 30, 0, 255);
2
int
green=map(значение температуры, -30, 30, 255, 0);
при температуре -30 светится только зеленый, при +30 только красный, а все промежуточные ардуинка сама вычисляет пропорционально.
нужно решать по пунктам, но уже не так как говорил лешак, точнее не совсем. допустим это уже сделали и мы не полные нубы
1. нужно постоить таблицу или график зависимости цвета от температуры (по идее дожно быть уже готово)
2. далее поигравшись со RGB добится нужных цветов и узнать как сделать переходы между ними (аналогично)
3. самое "простое" оформить в виде кода (буйство ума и фантазии. вот тут как раз и можно будет помочь. без исходных данных этот пункт почти бесполезен)
переделайте стандартный пример из ИДЕ Ардуино switchCase и будет вам и три цвета, и четыре
01
const
int
sensorMin = 0;
// sensor minimum, discovered through experiment
02
const
int
sensorMax = 600;
// sensor maximum, discovered through experiment
03
04
05
void
setup
() {
06
// initialize serial communication:
07
Serial
.begin(9600);
08
}
09
10
void
loop
() {
11
// read the sensor:
12
int
sensorReading = analogRead(A0);
13
// map the sensor range to a range of four options:
14
int
range = map(sensorReading, sensorMin, sensorMax, 0, 3);
15
16
// do something different depending on the
17
// range value:
18
switch
(range) {
19
case
0:
// your hand is on the sensor
20
Serial
.println(
"dark"
);
21
digitalWrite(blueLed,HIGH);
22
break
;
23
case
1:
// your hand is close to the sensor
24
Serial
.println(
"dim"
);
25
digitalWrite(greenLed,HIGH);
26
break
;
27
case
2:
// your hand is a few inches from the sensor
28
Serial
.println(
"medium"
);
29
digitalWrite(redLed,HIGH);
30
break
;
31
case
3:
// your hand is nowhere near the sensor
32
Serial
.println(
"bright"
);
33
digitalWrite(whiteLed,HIGH);
34
break
;
35
}
36
delay(1);
// delay in between reads for stability
37
}
Коллеги, я решил эту задачу. Если интерес не пропал, пишите на форум.
Термостат, работающий в диапазоне температур от -40 до +125, с установлением гистерезиса температур,
спектр свечения RGB LED в зависимости от температуры в заданный max и min значениях.
Интерес не пропал!
Уважаемые коллеги,
представляю на ваш суд свой проект. Он вполне рабочий.
Заранее признаю, что код далек от совершенства и свидетельствует о слабом владении языком программирования. Решения искал самостоятельно, кроме Интернета помочь было не кому, а сам я не программист и не электронщик. Поэтому прошу всех любителей и профессионалов присылать свои замечания и предложения. Именно в этом мне и представляется задача данного форума. Не оставайтесь равнодушными, потратьте 3-5 минут своего компьютерного времени, ведь именно это позволит довести проект до возможности его реализации.
Проект выполнен на основе Arduino Leonardo. В основе проекта – термостат, работающий в диапазоне от -50 до +205, оснащенный LCD дисплеем 16х2. Термостат запоминает в EEPROM значения устанавливаемых Max и Min температур. Реле включается при достижении нижнего порога температур и выключается при достижении верхнего порога. Это позволяет без нужды не «дергать» котел отопления за счет времени падения температуры от установленного верхнего предела до нижнего. Возможность установки отрицательных пороговых значений температур добавлена для универсальности данного устройства и расширения возможности его применения. В связи с тем, что EEPROM не сохраняет отрицательных значений, диапазон значений для записи в память изменен. После извлечения из памяти приводится опять в первоначальное состояние.
На дисплее отражаются данные о текущей температуре, измеряемой датчиком DS18B20, состояние выхода реле (OFF, ON), минимальное и максимальное пороговые значения температур.
Если температура, получаемая с датчика находится в пределах температур, заданных в качестве минимальной и максимальной, подключенный к выходам 9,10,11 RGB светодиод меняет свой цвет от синего, при нижнем пороговом уровне, до красного, при верхнем пороговом уровне.
Вот предлагаемый код, который я постарался прокомментировать как можно подробнее.
/***************************************************************************/
#include // подключение библиотеки внутренней памяти
#include // библиотека подключения дисплея по I2C
//ВАЖНО : при использовании I2C устройств - в скетче, библиотека Wire - должна быть объявлена первой,
//иначе - будут ошибки компиляции.
#include // библиотека управления дисплеем по I2C
#include // библиотека управления по однопроводной шине датчиком температуры
#include //библиотека управления датчиком DS18B20
#define ONE_WIRE_BUS 12 //датчик DS18B20 подключен на pin 12
OneWire oneWire(ONE_WIRE_BUS);// Настройка протокола 1-Wire для общения с датчиками в том числе и с DS18B20
DallasTemperature sensors(&oneWire); // Передача данных с DS18B20
LiquidCrystal_I2C lcd(0x27,16,2); // Настройки LCD дисплея: адрес 0x27, 16 символов, 2 строки
uint8_t gradus[8] = {0x0C,0x12,0x12,0x0C,0x0,0x0,0x0}; //создаем символ "градус"
uint8_t line[8] = {0x4,0x0,0x4,0x0,0x4,0x0,0x4}; //создаем символ разделительной черты
#define OUT1 A4 // устанавливаем выход для реле нижнего порогового значения на pin А4
#define OUT2 A5 // устанавливаем выход для реле верхнего порогового значения на pin А5
#define OUT3 A3 // устанавливаем выход на реле термостата на pin А3
int tempMin, tempMax; // задаем переменные для установки нижнего и верхнего пороговых значений температуры
int tempMin_mem, tempMax_mem; // задаем переменные для записи в ЕЕРRОМ данных о пороговых температурах
int red = 9; // определяем пин 9 (ШИМ) для красной линии RGB LED
int green = 10; // определяем пин 10 (ШИМ) для зеленой линии RGB LED
int blue = 11; // определяем пин 11 (ШИМ) для синей линии RGB LED
float tempMin_led, tempMax_led; // задаем переменные для пороговых значений управления RGB LED
float temperature; // задаем переменную для измерения температуры
float delta; // задаем переменную разницы (гистерезиса) пороговых значений температуры
byte key() // задаем возвращаемые значения для переменной KEY - сигнала от кнопок управления
{
int val = analogRead(0); // значение сигнала от кнопок получаем с pin А0
if (val < 50) return 5; // при нажатии кнопки RIGHT возвращаем значение 5
else if (val < 150) return 3; // при нажатии кнопки UP возвращаем значение 3
else if (val < 350) return 4; // при нажатии кнопки DOWN возвращаем значение 4
else if (val < 500) return 2; // при нажатии кнопки LEFT возвращаем значение 2
else if (val < 800) return 1; // при нажатии кнопки SELECT возвращаем значение 1
else return 0; // если кнопки не нажаты - возвращаемое значение 0
}
/************* Подпрограмма меню установок значений температуры **********************/
void SetupMenu()
{
byte position; // задаем переменную для определения позиции меню установок значений температуры
digitalWrite(OUT1, LOW); // при входе в режим установок температуры выключаем все реле
digitalWrite(OUT2, LOW);
digitalWrite(OUT3, LOW);
lcd.clear(); // очищаем экран дисплея
lcd.setCursor(0, 0); // курсор на позицию 0 строки 1
lcd.print("Min ");
lcd.setCursor(0, 1); // курсор на позицию 0 строки 2
lcd.print("Max ");
lcd.blink(); // курсор в мигающем режиме
while(1) // Цикл 1. Условия выхода не установлены. Выход из цикла при перезагрузке контроллера нажатием кнопки RESET
{
byte KEY = key(); // переменная KEY принимает значение key возвращаемое при нажатии кнопок - читаем значение кнопок
lcd.setCursor(4, 0); // курсор на позицию 4 строки 1
// Если нижнее пороговое значение температуры представлено положительным числом от 0 и выше,
// пишем значение, добавляя знак "+", например, +36
if (tempMin > 0)
{
lcd.setCursor(4, 0); // курсор на 4 позицию 1 строки
lcd.print("+");
lcd.print(tempMin); // пишем нижнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
// Если нижнее пороговое значение температуры имеет отрицательное значение от 0 и ниже,
// пишем значение, со знаком "-", который присваивается программно, например, -3
else if (tempMin <= 0)
{
lcd.setCursor(4, 0); // курсор на 4 позицию 1 строки
lcd.print(tempMin); // пишем нижнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
lcd.print("C ");
lcd.setCursor(4, 1); // курсор на позицию 4 строки 2
// Если верхнее пороговое значение температуры представлено положительным числом от 0 и выше,
// пишем значение, добавляя знак "+", например, +36
if (tempMax > 0)
{
lcd.setCursor(4, 1); // курсор на 4 позицию 1 строки
lcd.print("+");
lcd.print(tempMax); // пишем верхнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
// Если верхнее пороговое значение температуры имеет отрицательное значение от 0 и ниже,
// пишем значение, со знаком "-", который присваивается программно, например, -3
else if (tempMax <= 0)
{
lcd.setCursor(4, 1); // курсор на 4 позицию 1 строки
lcd.print(tempMax); // пишем верхнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
lcd.print("C ");
/***** Обработка команд кнопок, установка и запись в EEPROM пороговых значений температуры ******/
if (position == 0) // в режиме установки нижнего порогового значения температуры
{
lcd.setCursor(3, 0); // курсор на позицию 3 строки 1
if (KEY == 2) // если нажата кнопка 2 "LEFT"
{
tempMin--; // уменьшаем на единицу нижнее пороговое значение температуры
tempMin_mem = map (tempMin,-50,205,0,255); // изменяем значение в формат 0-255 для записи в EEPROM (не запоминает отрицательных значений)
EEPROM.write(1, tempMin_mem); // нижнее пороговое значение температуры сохраняем в ячейке 1 EEPROM
}
else if (KEY == 5) // если нажата кнопка 5 "RIGHT"
{
tempMin++; // увеличиваем на единицу нижнее пороговое значение температуры
tempMin_mem = map (tempMin,-50,205,0,255); // изменяем к положительным значениям
EEPROM.write(1, tempMin_mem); // сохраняем в ячейке 1 EEPROM
}
}
if (position == 1) // в режиме установки верзнего порогового значения температуры
{
lcd.setCursor(3, 1); // курсор на позицию 3 строки 2
if (KEY == 2) // если нажата кнопка 2 "LEFT"
{
tempMax--; // уменьшаем на единицу верхнее пороговое значение температуры
tempMax_mem = map (tempMax,-50,205,0,255); // изменяем значение в формат 0-255 для записи в EEPROM
EEPROM.write(2, tempMax_mem); // верхнее пороговое значение температуры сохраняем в ячейке 2 EEPROM
}
else if (KEY == 5) // если нажата кнопка 5 "RIGHT"
{
tempMax++; // увеличиваем на единицу верхнеее пороговое значение температуры
tempMax_mem = map (tempMax,-50,205,0,255); // изменяем к положительным значениям
EEPROM.write(2, tempMax_mem); // сохраняем в ячейке 2 EEPROM
}
}
/*
Кнопками 3 "UP" и 4 "DOWN" изменяем режим установок
нижнего и верхнего пороговых значений температуры
*/
if (KEY == 3) // если нажата кнопка 3 "UP"
{
position--; // значение режимов меню уменьшаем на 1
}
else if (KEY == 4) // если нажата кнопка 4 "DOWN"
{
position++; // значение режимов меню увеличиваем на 1
}
if (position > 1) // при значении позиции больше 1
{
position = 0; // значение позиции приобретает значение 0
}
delay(200);
}
} // закрываем подпрограмму void SetupMenu
/*****************************************************/
void setup()
{
lcd.init(); // инициализация дисплея
lcd.backlight(); // Включаем подсветку дисплея
lcd.createChar(1, gradus); // записываем в память дисплея символ "градус"
lcd.createChar(2, line); // записываем в память дисплея символ "разделительная линия"
sensors.begin(); // инициализируем датчик температуры
pinMode(OUT1, OUTPUT); // определяем pin реле нижнего порогового значения в качестве выхода
pinMode(OUT2, OUTPUT); // определяем pin реле верхнего порогового значения в качестве выхода
pinMode(OUT3, OUTPUT); // определяем pin реле 3 термостата в качестве выхода
pinMode(red, OUTPUT); // определяем красную линию LED в качестве выхода
pinMode(green, OUTPUT); // определяем зеленую линию LED в качестве выхода
pinMode(blue, OUTPUT); // определяем синюю линию LED в качестве выхода
tempMin_mem = EEPROM.read(1); // читаем из EEPROM записанное нижнее пороговое значение температуры
tempMax_mem = EEPROM.read(2); // читаем из EEPROM записанное верхнее пороговое значение температуры
tempMin = map (tempMin_mem, 0,255,-50,205); // значение из EEPROM переводим в нижнее пороговое значение температуры
tempMax = map (tempMax_mem, 0,255,-50,205); // значение из EEPROM переводим в верхнее пороговое значение температуры
/*******/ Serial.begin(9600);
} // завершаем цикл void setup
/*****************************************************/
void loop()
{
if (key() == 1) // если нажата кнопка 1 "SELECT"
{
SetupMenu(); // запускаем подпрограмму SetupMenu установок пороговых значений температуры
}
else if (key() == 4) // при нажатии кнопки 4 "DOWN"
{
lcd.noBacklight(); // выключаем подсветку дисплея
}
else if (key() == 3) // при нажатии кнопки 3 "UP"
{
lcd.backlight(); // включаем подсветку дисплея
}
sensors.requestTemperatures(); // датчик регистрирует температуру
// переменной temperature присваивается значение, полученное с датчика температуры
float temperature = sensors.getTempCByIndex(0);
/**************** Управление реле термостата *******************/
if (temperature <= tempMin) // если температура ниже нижнего порогового значения
{
digitalWrite(OUT1, HIGH); // включаем Реле 1
}
else
{
digitalWrite(OUT1, LOW); // если нет, выключаем Реле 1
}
if (temperature <= tempMax) // если температура ниже верхнего порогового значения
{
digitalWrite(OUT2, HIGH); // включаем Реле 2
}
else
{
digitalWrite(OUT2, LOW); // если нет, выключаем Реле 2
}
/* Реле 3 термостата включено до достижения верхнего порогового значения.
После достижения верхнего порогового значения, реле 3 отключается
и включается при падении температуры ниже нижнего порогового значения.
Температура поддерживается в диапазоне от нижнего до верхнегоо пороговых значений.
*/
if ((digitalRead(OUT1)) && (digitalRead(OUT2))) // если получаем значение с выходов OUT1 и OUT2
{
digitalWrite(OUT3, HIGH); // включаем реле 3 термостата
}
else if (!digitalRead(OUT2)) // если игнорируем значение с выхода OUT2
{
digitalWrite(OUT3, LOW); // выключаем реле 3 термостата
}
/***** Пишем первую строку дисплея *******************/
lcd.setCursor(0, 0); // курсор на 0 позицию 1 строки
lcd.print("Min");
lcd.setCursor(4, 0); // курсор на 4 позицию 1 строки
// Если нижнее пороговое значение температуры представлено двухзначным числом от 10 до 99,
// пишем значение, добавляя знак "+", например, +36
if ((tempMin >= 10)&&(tempMin < 100))
{
lcd.setCursor(4, 0); // курсор на 4 позицию 1 строки
lcd.print("+");
lcd.print(tempMin); // пишем нижнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
// Если нижнее пороговое значение температуры имеет отрицательное однозначное значение от -10 до 0,
// пишем значение, со знаком "-", который присваивается программно, например, -3
else if ((tempMin > -10)&&(tempMin <= 0))
{
lcd.setCursor(4, 0); // курсор на 4 позицию 1 строки
lcd.print(tempMin); // пишем нижнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
// Если нижнее пороговое значение температуры имеет положительное однозначное значение от 0 до 10,
// пишем значение, добавляя знак "+", например, +6
else if ((tempMin < 10)&&(tempMin >= 0))
{
lcd.setCursor(4, 0); // курсор на 4 позицию 1 строки
lcd.print("+");
lcd.print(tempMin); // выводим нижнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
// во всех остальных случаях, когда выводится 3-х символьное значение:
// если нижнее пороговое значение температуры положительное трехзначное, например, 102 (знак "+" не добавляется)
// если нижнее пороговое значение температуры отрицательное двухзначное, например, -18
else
{
lcd.setCursor(4, 0); // курсор на 4 позицию 1 строки
lcd.print(tempMin); // выводим нижнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
lcd.setCursor(8, 0); // курсор на 8 позицию 1 строки
lcd.write(2); // рисуем разделительную линию
lcd.setCursor(9, 0); // курсор на 9 позицию 1 строки
/* Выводим значение текущей температуры и сносим лишние символы при переходе разряда показаний.
Должно быть пять символов отображения текущей температуры, с учетом того, что датчик сам
присваивает знак "-" отрицательным значениям
*/
// Если температура имеет двухзначное значение до запятой, от 10 до 99,
// пишем ее, добавляя знак "+", например, +36,6
if ((temperature >= 10)&&(temperature < 100))
{
lcd.setCursor(9, 0); // курсор на 9 позицию 1 строки
lcd.print("+");
lcd.print(temperature, 1); // выводим текущее значение температуры, (значение 1 - два знака после запятой)
lcd.setCursor(14, 0); // курсор на 14 позицию 1 строки
lcd.write(1); // рисуем символ "градус"
lcd.setCursor(15, 0); // курсор на 15 позицию 1 строки
lcd.print("C");
}
// Если температура имеет отрицательное однозначное значение до запятой, от -10 до 0,
// пишем ее, со знаком "-", который напишет сам датчик например, -3,6
else if ((temperature > -10)&&(temperature <= 0))
{
lcd.setCursor(10, 0); // курсор на 10 позицию 1 строки
lcd.print(temperature, 1); // выводим текущее значение температуры
lcd.setCursor(14, 0); // курсор на 14 позицию 1 строки
lcd.write(1); // рисуем символ "градус"
lcd.setCursor(15, 0); // курсор на 15 позицию 1 строки
lcd.print("C");
}
// Если температура имеет положительное однозначное значение до запятой, от 0 до 10,
// пишем ее, со знаком "+", например, +3,6
else if ((temperature < 10)&&(temperature >= 0))
{
lcd.setCursor(10, 0); // курсор на 12 позицию 1 строки
lcd.print("+");
lcd.print(temperature, 1); // выводим текущее значение температуры
lcd.setCursor(14, 0); // курсор на 14 позицию 1 строки
lcd.write(1); // рисуем символ "градус"
lcd.setCursor(15, 0); // курсор на 15 позицию 1 строки
lcd.print("C");
}
// во всех остальных случаях, когда выводится пяти символьное значение:
// если значение температуры положительное трехзначное, например, 102,5 (знак "+" не добавляется)
// если значение температуры отрицательное двухзначное, например, -18,4
else
{
lcd.setCursor(9, 0); // курсор на 9 позицию 1 строки
lcd.print(temperature, 1); // выводим текущее значение температуры
lcd.setCursor(14, 0); // курсор на 14 позицию 1 строки
lcd.write(1); // рисуем символ "градус"
lcd.setCursor(15, 0); // курсор на 15 позицию 1 строки
lcd.print("C");
}
/****** Пишем вторую строку дисплея ********************/
lcd.setCursor(0, 1); // курсор на 0 позицию 2 строки
lcd.print("Max");
lcd.setCursor(4, 1); // курсор на 4 позицию 2 строки
// Если верхнее пороговое значение температуры представлено двухзначным числом от 10 до 99,
// пишем значение, добавляя знак "+", например, +36
if ((tempMax >= 10)&&(tempMax < 100))
{
lcd.setCursor(4, 1); // курсор на 4 позицию 1 строки
lcd.print("+");
lcd.print(tempMax); // пишем верхнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
// Если верхнее пороговое значение температуры имеет отрицательное однозначное значение от -10 до 0,
// пишем значение, со знаком "-", который присваивается программно, например, -3
else if ((tempMax > -10)&&(tempMax <= 0))
{
lcd.setCursor(4, 1); // курсор на 4 позицию 1 строки
lcd.print(tempMax); // пишем верхнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
// Если верхнее пороговое значение температуры имеет положительное однозначное значение от 0 до 10,
// пишем значение, добавляя знак "+", например, +6
else if ((tempMax < 10)&&(tempMax >= 0))
{
lcd.setCursor(4, 1); // курсор на 4 позицию 1 строки
lcd.print("+");
lcd.print(tempMax); // выводим верхнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
// во всех остальных случаях, когда выводится 3-х символьное значение:
// если верхнее пороговое значение температуры положительное трехзначное, например, 102 (знак "+" не добавляется)
// если верхнее пороговое значение температуры отрицательное двухзначное, например, -18
else
{
lcd.setCursor(4, 1); // курсор на 4 позицию 1 строки
lcd.print(tempMax); // выводим верхнее пороговое значение температуры
lcd.write(1); // рисуем символ "градус"
}
lcd.setCursor(8, 1); // курсор на 8 позицию 1 строки
lcd.write(2); // рисуем разделительную линию
lcd.setCursor(9,1); // курсор на 8 позицию 2 строки
lcd.print("OUT");
lcd.setCursor(13,1); // курсор на 8 позицию 2 строки
if (digitalRead(OUT3)) // если получаем значение с выхода 3
{
lcd.print("ON "); // пишем состояние реле 3 "ON"
}
else // в противном случае
{
lcd.print("OFF"); // пишем состояние реле 3 "OFF"
}
delay(100); // пауза 0.1 секунда
/************* Управление R G B L E D ********************************/
/* устанавливаем тип переменных tempMin_led и tempMax_led для вычислений с плавающей запятой
и определяем их значение равное установленным пороговым значениям температур */
tempMin_led = (float)tempMin / 1.0;
tempMax_led = (float)tempMax / 1.0;
/* значение переменной delta вычисляем как положительное значение разницы пороговых температур
разделенное на 25 оттенков цветового спектра, подлежащего отображению RGB LED в зависимости
от температуры и в пределах значений заданных параметрами tempMin и tempMax
(с учетом того, что всегда tempMin < tempMax) */
delta = ((tempMax_led - tempMin_led) / 25); // разницу температур / 25 оттенков
/* Устанавливаем уровень ШИМ сигнала на красной, зеленой и синей линиях RGB
в зависимости от температуры и в пределах значений заданных параметрами tempMin и tempMax
путем поэтапного прибавления к значению нижнего уровня температуры кратного значения delta
*/
if (temperature < tempMin_led) // при значении температуры ниже нижнего заданного значения
{
analogWrite (red, 0); // отображается синий
analogWrite (green, 0);
analogWrite (blue, 255);
}
/* Четыре основных этапа изменение цвета:
1. От синего к голубому
2. От голубого к зеленому
3. От зеленого к желтому
4. От желтого к красному
Каждый этап состоит из 6 частей.
Значение ШИМ = 255 / 6 = 42.5. Округленно 42 = шаг изменения значения функции analogWrite
*/
// от синего к голубому
else if (temperature >= tempMin_led && temperature <= (tempMin_led + delta))
{
analogWrite (red, 0);
analogWrite (green, 0);
analogWrite (blue, 255);
}
else if (temperature > (tempMin_led + delta) && temperature <= (tempMin_led + (2*delta)))
{
analogWrite (red, 0);
analogWrite (green, 42);
analogWrite (blue, 255);
}
else if (temperature >(tempMin_led+(2*delta)) && temperature <= (tempMin_led + (3*delta)))
{
analogWrite (red, 0);
analogWrite (green, 85);
analogWrite (blue, 255);
}
else if (temperature > (tempMin_led + (3*delta)) && temperature <= (tempMin_led + (4*delta)))
{
analogWrite (red, 0);
analogWrite (green, 127);
analogWrite (blue, 255);
}
else if (temperature > (tempMin_led + (4*delta)) && temperature <= (tempMin_led + (5*delta)))
{
analogWrite (red, 0);
analogWrite (green, 170);
analogWrite (blue, 255);
}
else if (temperature > (tempMin_led + (5*delta)) && temperature <= (tempMin_led + (6*delta)))
{
analogWrite (red, 0);
analogWrite (green, 212);
analogWrite (blue, 255);
}
else if (temperature > (tempMin_led + (6*delta)) && temperature <= (tempMin_led + (7*delta)))
{
analogWrite (red, 0);
analogWrite (green, 255);
analogWrite (blue, 255);
}
// от голубого к зеленому
else if (temperature > (tempMin_led + (7*delta)) && temperature <= (tempMin_led + (8*delta)))
{
analogWrite (red, 0);
analogWrite (green, 255);
analogWrite (blue, 212);
}
else if (temperature > (tempMin_led + (8*delta)) && temperature <= (tempMin_led + (9*delta)))
{
analogWrite (red, 0);
analogWrite (green, 255);
analogWrite (blue, 170);
}
else if (temperature > (tempMin_led + (9*delta)) && temperature <= (tempMin_led + (10*delta)))
{
analogWrite (red, 0);
analogWrite (green, 255);
analogWrite (blue, 127);
}
else if (temperature > (tempMin_led + (10*delta)) && temperature <= (tempMin_led + (11*delta)))
{
analogWrite (red, 0);
analogWrite (green, 255);
analogWrite (blue, 85);
}
else if (temperature > (tempMin_led + (11*delta)) && temperature <= (tempMin_led + (12*delta)))
{
analogWrite (red, 0);
analogWrite (green, 255);
analogWrite (blue, 42);
}
else if (temperature > (tempMin_led + (12*delta)) && temperature <= (tempMin_led + (13*delta)))
{
analogWrite (red, 0);
analogWrite (green, 255);
analogWrite (blue, 0);
}
// от зеленого к желтому
else if (temperature > (tempMin_led + (13*delta)) && temperature <= (tempMin_led + (14*delta)))
{
analogWrite (red, 42);
analogWrite (green, 255);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (14*delta)) && temperature <= (tempMin_led + (15*delta)))
{
analogWrite (red, 85);
analogWrite (green, 255);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (15*delta)) && temperature <= (tempMin_led + (16*delta)))
{
analogWrite (red, 127);
analogWrite (green, 255);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (16*delta)) && temperature <= (tempMin_led + (17*delta)))
{
analogWrite (red, 170);
analogWrite (green, 255);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (17*delta)) && temperature <= (tempMin_led + (18*delta)))
{
analogWrite (red, 212);
analogWrite (green, 255);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (18*delta)) && temperature <= (tempMin_led + (19*delta)))
{
analogWrite (red, 255);
analogWrite (green, 255);
analogWrite (blue, 0);
}
// от желтого к красному
else if (temperature > (tempMin_led + (19*delta)) && temperature <= (tempMin_led + (20*delta)))
{
analogWrite (red, 255);
analogWrite (green, 212);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (20*delta)) && temperature <= (tempMin_led + (21*delta)))
{
analogWrite (red, 255);
analogWrite (green, 170);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (21*delta)) && temperature <= (tempMin_led + (22*delta)))
{
analogWrite (red, 255);
analogWrite (green, 127);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (22*delta)) && temperature <= (tempMin_led + (23*delta)))
{
analogWrite (red, 255);
analogWrite (green, 85);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (23*delta)) && temperature <= (tempMin_led + (24*delta)))
{
analogWrite (red, 255);
analogWrite (green, 42);
analogWrite (blue, 0);
}
else if (temperature > (tempMin_led + (24*delta)) && temperature <= (tempMin_led + (25*delta)))
{
analogWrite (red, 255);
analogWrite (green, 0);
analogWrite (blue, 0);
}
else if (temperature >= tempMax_led) // при значении температуры выше высшего заданного значения
{
analogWrite (red, 255); // отображается красный
analogWrite (green, 0);
analogWrite (blue, 0);
}
/******/ Serial.print("temperature ");
/******/ Serial.println(temperature);
/******/ Serial.print("Min ");
/******/ Serial.println(tempMin);
/******/ Serial.print("Max ");
/******/ Serial.println(tempMax);
/******/ Serial.print("OUT ");
/******/ if (digitalRead(OUT3)) {Serial.println("ON");}
/******/ else {Serial.println("OFF");}
} // закрываем цикл void loop
/**************************************************************************/
В данном сообщении, я не стал вдаваться в технические подробности устройства и подробные описания его компонентов.
Если кому интересно, пишите на личную почту (адрес s-chuprin@mail.ru ), пришлю схемы, описание, фото и все остальное.
Удачи всем, жду Ваших замечаний и правок.
Кстати, вот проект,
http://ergoz.ru/electronics/arduino/rgb-led-strip-upravlyaemyiy-arduino....
в котором светодиод изменяет цвет в зависимости от диапазона температур, задаваемых в программном коде. Я этот проект повторил на макетной плате. Работает, в том числе в диапазоне отрицательных значений (у меня в морозильной камере -16 гр.). Цвет RGB диода изменяется плавно без скачков. Красиво, но RGB диоды в этом проекте горят слабо, в пол силы. Интересно, почему? А так проект совсем не плох и мог бы быть основой для разработки собственных устройств. Тем более, что аналогичных проектов не так много на российских и зарубежных сайтах.
Вот теперь все. Жду комментариев.
001
#include <EEPROM.h> // подключение библиотеки внутренней памяти
002
#include <Wire.h> // библиотека подключения дисплея по I2C
003
//ВАЖНО : при использовании I2C устройств - в скетче, библиотека Wire - должна быть объявлена первой,
004
//иначе - будут ошибки компиляции.
005
#include <LiquidCrystal_I2C.h> // библиотека управления дисплеем по I2C
006
#include <OneWire.h> // библиотека управления по однопроводной шине датчиком температуры
007
#include <DallasTemperature.h> //библиотека управления датчиком DS18B20
008
#define ONE_WIRE_BUS 12 //датчик DS18B20 подключен на pin 12
009
010
OneWire oneWire(ONE_WIRE_BUS);
// Настройка протокола 1-Wire для общения с датчиками в том числе и с DS18B20
011
DallasTemperature sensors(&oneWire);
// Передача данных с DS18B20
012
LiquidCrystal_I2C lcd(0x27,16,2);
// Настройки LCD дисплея: адрес 0x27, 16 символов, 2 строки
013
014
uint8_t gradus[8] = {0x0C,0x12,0x12,0x0C,0x0,0x0,0x0};
//создаем символ "градус"
015
uint8_t line[8] = {0x4,0x0,0x4,0x0,0x4,0x0,0x4};
//создаем символ разделительной черты
016
017
#define OUT1 A4 // устанавливаем выход для реле нижнего порогового значения на pin А4
018
#define OUT2 A5 // устанавливаем выход для реле верхнего порогового значения на pin А5
019
#define OUT3 A3 // устанавливаем выход на реле термостата на pin А3
020
021
int
tempMin, tempMax;
// задаем переменные для установки нижнего и верхнего пороговых значений температуры
022
int
tempMin_mem, tempMax_mem;
// задаем переменные для записи в ЕЕРRОМ данных о пороговых температурах
023
024
int
red = 9;
// определяем пин 9 (ШИМ) для красной линии RGB LED
025
int
green = 10;
// определяем пин 10 (ШИМ) для зеленой линии RGB LED
026
int
blue = 11;
// определяем пин 11 (ШИМ) для синей линии RGB LED
027
028
float
tempMin_led, tempMax_led;
// задаем переменные для пороговых значений управления RGB LED
029
float
temperature;
// задаем переменную для измерения температуры
030
float
delta;
// задаем переменную разницы (гистерезиса) пороговых значений температуры
031
032
byte
key()
// задаем возвращаемые значения для переменной KEY - сигнала от кнопок управления
033
{
034
int
val = analogRead(0);
// значение сигнала от кнопок получаем с pin А0
035
if
(val < 50)
return
5;
// при нажатии кнопки RIGHT возвращаем значение 5
036
else
if
(val < 150)
return
3;
// при нажатии кнопки UP возвращаем значение 3
037
else
if
(val < 350)
return
4;
// при нажатии кнопки DOWN возвращаем значение 4
038
else
if
(val < 500)
return
2;
// при нажатии кнопки LEFT возвращаем значение 2
039
else
if
(val < 800)
return
1;
// при нажатии кнопки SELECT возвращаем значение 1
040
else
return
0;
// если кнопки не нажаты - возвращаемое значение 0
041
}
042
043
/************* Подпрограмма меню установок значений температуры **********************/
044
void
SetupMenu()
045
{
046
byte
position;
// задаем переменную для определения позиции меню установок значений температуры
047
digitalWrite(OUT1, LOW);
// при входе в режим установок температуры выключаем все реле
048
digitalWrite(OUT2, LOW);
049
digitalWrite(OUT3, LOW);
050
051
lcd.clear();
// очищаем экран дисплея
052
lcd.setCursor(0, 0);
// курсор на позицию 0 строки 1
053
lcd.print(
"Min "
);
054
lcd.setCursor(0, 1);
// курсор на позицию 0 строки 2
055
lcd.print(
"Max "
);
056
lcd.blink();
// курсор в мигающем режиме
057
058
while
(1)
// Цикл 1. Условия выхода не установлены. Выход из цикла при перезагрузке контроллера нажатием кнопки RESET
059
{
060
byte
KEY = key();
// переменная KEY принимает значение key возвращаемое при нажатии кнопок - читаем значение кнопок
061
062
lcd.setCursor(4, 0);
// курсор на позицию 4 строки 1
063
// Если нижнее пороговое значение температуры представлено положительным числом от 0 и выше,
064
// пишем значение, добавляя знак "+", например, +36
065
if
(tempMin > 0)
066
{
067
lcd.setCursor(4, 0);
// курсор на 4 позицию 1 строки
068
lcd.print(
"+"
);
069
lcd.print(tempMin);
// пишем нижнее пороговое значение температуры
070
lcd.write(1);
// рисуем символ "градус"
071
}
072
073
// Если нижнее пороговое значение температуры имеет отрицательное значение от 0 и ниже,
074
// пишем значение, со знаком "-", который присваивается программно, например, -3
075
else
if
(tempMin <= 0)
076
{
077
lcd.setCursor(4, 0);
// курсор на 4 позицию 1 строки
078
lcd.print(tempMin);
// пишем нижнее пороговое значение температуры
079
lcd.write(1);
// рисуем символ "градус"
080
}
081
lcd.print(
"C "
);
082
083
lcd.setCursor(4, 1);
// курсор на позицию 4 строки 2
084
085
// Если верхнее пороговое значение температуры представлено положительным числом от 0 и выше,
086
// пишем значение, добавляя знак "+", например, +36
087
if
(tempMax > 0)
088
{
089
lcd.setCursor(4, 1);
// курсор на 4 позицию 1 строки
090
lcd.print(
"+"
);
091
lcd.print(tempMax);
// пишем верхнее пороговое значение температуры
092
lcd.write(1);
// рисуем символ "градус"
093
}
094
095
// Если верхнее пороговое значение температуры имеет отрицательное значение от 0 и ниже,
096
// пишем значение, со знаком "-", который присваивается программно, например, -3
097
else
if
(tempMax <= 0)
098
{
099
lcd.setCursor(4, 1);
// курсор на 4 позицию 1 строки
100
lcd.print(tempMax);
// пишем верхнее пороговое значение температуры
101
lcd.write(1);
// рисуем символ "градус"
102
}
103
lcd.print(
"C "
);
104
105
/***** Обработка команд кнопок, установка и запись в EEPROM пороговых значений температуры ******/
106
if
(position == 0)
// в режиме установки нижнего порогового значения температуры
107
{
108
lcd.setCursor(3, 0);
// курсор на позицию 3 строки 1
109
if
(KEY == 2)
// если нажата кнопка 2 "LEFT"
110
{
111
tempMin--;
// уменьшаем на единицу нижнее пороговое значение температуры
112
tempMin_mem = map (tempMin,-50,205,0,255);
// изменяем значение в формат 0-255 для записи в EEPROM (не запоминает отрицательных значений)
113
EEPROM.write(1, tempMin_mem);
// нижнее пороговое значение температуры сохраняем в ячейке 1 EEPROM
114
}
115
else
if
(KEY == 5)
// если нажата кнопка 5 "RIGHT"
116
{
117
tempMin++;
// увеличиваем на единицу нижнее пороговое значение температуры
118
tempMin_mem = map (tempMin,-50,205,0,255);
// изменяем к положительным значениям
119
EEPROM.write(1, tempMin_mem);
// сохраняем в ячейке 1 EEPROM
120
}
121
}
122
123
if
(position == 1)
// в режиме установки верзнего порогового значения температуры
124
{
125
lcd.setCursor(3, 1);
// курсор на позицию 3 строки 2
126
if
(KEY == 2)
// если нажата кнопка 2 "LEFT"
127
{
128
tempMax--;
// уменьшаем на единицу верхнее пороговое значение температуры
129
tempMax_mem = map (tempMax,-50,205,0,255);
// изменяем значение в формат 0-255 для записи в EEPROM
130
EEPROM.write(2, tempMax_mem);
// верхнее пороговое значение температуры сохраняем в ячейке 2 EEPROM
131
}
132
else
if
(KEY == 5)
// если нажата кнопка 5 "RIGHT"
133
{
134
tempMax++;
// увеличиваем на единицу верхнеее пороговое значение температуры
135
tempMax_mem = map (tempMax,-50,205,0,255);
// изменяем к положительным значениям
136
EEPROM.write(2, tempMax_mem);
// сохраняем в ячейке 2 EEPROM
137
}
138
}
139
/*
140
Кнопками 3 "UP" и 4 "DOWN" изменяем режим установок
141
нижнего и верхнего пороговых значений температуры
142
*/
143
if
(KEY == 3)
// если нажата кнопка 3 "UP"
144
{
145
position--;
// значение режимов меню уменьшаем на 1
146
}
147
else
if
(KEY == 4)
// если нажата кнопка 4 "DOWN"
148
{
149
position++;
// значение режимов меню увеличиваем на 1
150
}
151
if
(position > 1)
// при значении позиции больше 1
152
{
153
position = 0;
// значение позиции приобретает значение 0
154
}
155
delay(200);
156
}
157
}
// закрываем подпрограмму void SetupMenu
158
/*****************************************************/
159
160
void
setup
()
161
{
162
lcd.init();
// инициализация дисплея
163
lcd.backlight();
// Включаем подсветку дисплея
164
lcd.createChar(1, gradus);
// записываем в память дисплея символ "градус"
165
lcd.createChar(2, line);
// записываем в память дисплея символ "разделительная линия"
166
167
sensors.begin();
// инициализируем датчик температуры
168
169
pinMode(OUT1, OUTPUT);
// определяем pin реле нижнего порогового значения в качестве выхода
170
pinMode(OUT2, OUTPUT);
// определяем pin реле верхнего порогового значения в качестве выхода
171
pinMode(OUT3, OUTPUT);
// определяем pin реле 3 термостата в качестве выхода
172
pinMode(red, OUTPUT);
// определяем красную линию LED в качестве выхода
173
pinMode(green, OUTPUT);
// определяем зеленую линию LED в качестве выхода
174
pinMode(blue, OUTPUT);
// определяем синюю линию LED в качестве выхода
175
176
tempMin_mem = EEPROM.read(1);
// читаем из EEPROM записанное нижнее пороговое значение температуры
177
tempMax_mem = EEPROM.read(2);
// читаем из EEPROM записанное верхнее пороговое значение температуры
178
179
tempMin = map (tempMin_mem, 0,255,-50,205);
// значение из EEPROM переводим в нижнее пороговое значение температуры
180
tempMax = map (tempMax_mem, 0,255,-50,205);
// значение из EEPROM переводим в верхнее пороговое значение температуры
181
182
/*******/
Serial
.begin(9600);
183
184
}
// завершаем цикл void setup
185
/*****************************************************/
186
187
void
loop
()
188
{
189
if
(key() == 1)
// если нажата кнопка 1 "SELECT"
190
{
191
SetupMenu();
// запускаем подпрограмму SetupMenu установок пороговых значений температуры
192
}
193
else
if
(key() == 4)
// при нажатии кнопки 4 "DOWN"
194
{
195
lcd.noBacklight();
// выключаем подсветку дисплея
196
}
197
else
if
(key() == 3)
// при нажатии кнопки 3 "UP"
198
{
199
lcd.backlight();
// включаем подсветку дисплея
200
}
201
202
sensors.requestTemperatures();
// датчик регистрирует температуру
203
// переменной temperature присваивается значение, полученное с датчика температуры
204
float
temperature = sensors.getTempCByIndex(0);
205
206
/**************** Управление реле термостата *******************/
207
208
if
(temperature <= tempMin)
// если температура ниже нижнего порогового значения
209
{
210
digitalWrite(OUT1, HIGH);
// включаем Реле 1
211
}
212
else
213
{
214
digitalWrite(OUT1, LOW);
// если нет, выключаем Реле 1
215
}
216
if
(temperature <= tempMax)
// если температура ниже верхнего порогового значения
217
{
218
digitalWrite(OUT2, HIGH);
// включаем Реле 2
219
}
220
else
221
{
222
digitalWrite(OUT2, LOW);
// если нет, выключаем Реле 2
223
}
224
/* Реле 3 термостата включено до достижения верхнего порогового значения.
225
После достижения верхнего порогового значения, реле 3 отключается
226
и включается при падении температуры ниже нижнего порогового значения.
227
Температура поддерживается в диапазоне от нижнего до верхнегоо пороговых значений.
228
*/
229
230
if
((digitalRead(OUT1)) && (digitalRead(OUT2)))
// если получаем значение с выходов OUT1 и OUT2
231
{
232
digitalWrite(OUT3, HIGH);
// включаем реле 3 термостата
233
}
234
else
if
(!digitalRead(OUT2))
// если игнорируем значение с выхода OUT2
235
{
236
digitalWrite(OUT3, LOW);
// выключаем реле 3 термостата
237
}
238
239
/***** Пишем первую строку дисплея *******************/
240
241
lcd.setCursor(0, 0);
// курсор на 0 позицию 1 строки
242
lcd.print(
"Min"
);
243
lcd.setCursor(4, 0);
// курсор на 4 позицию 1 строки
244
245
// Если нижнее пороговое значение температуры представлено двухзначным числом от 10 до 99,
246
// пишем значение, добавляя знак "+", например, +36
247
if
((tempMin >= 10)&&(tempMin < 100))
248
{
249
lcd.setCursor(4, 0);
// курсор на 4 позицию 1 строки
250
lcd.print(
"+"
);
251
lcd.print(tempMin);
// пишем нижнее пороговое значение температуры
252
lcd.write(1);
// рисуем символ "градус"
253
}
254
255
// Если нижнее пороговое значение температуры имеет отрицательное однозначное значение от -10 до 0,
256
// пишем значение, со знаком "-", который присваивается программно, например, -3
257
else
if
((tempMin > -10)&&(tempMin <= 0))
258
{
259
lcd.setCursor(4, 0);
// курсор на 4 позицию 1 строки
260
lcd.print(tempMin);
// пишем нижнее пороговое значение температуры
261
lcd.write(1);
// рисуем символ "градус"
262
}
263
264
// Если нижнее пороговое значение температуры имеет положительное однозначное значение от 0 до 10,
265
// пишем значение, добавляя знак "+", например, +6
266
else
if
((tempMin < 10)&&(tempMin >= 0))
267
{
268
lcd.setCursor(4, 0);
// курсор на 4 позицию 1 строки
269
lcd.print(
"+"
);
270
lcd.print(tempMin);
// выводим нижнее пороговое значение температуры
271
lcd.write(1);
// рисуем символ "градус"
272
}
273
274
// во всех остальных случаях, когда выводится 3-х символьное значение:
275
// если нижнее пороговое значение температуры положительное трехзначное, например, 102 (знак "+" не добавляется)
276
// если нижнее пороговое значение температуры отрицательное двухзначное, например, -18
277
else
278
{
279
lcd.setCursor(4, 0);
// курсор на 4 позицию 1 строки
280
lcd.print(tempMin);
// выводим нижнее пороговое значение температуры
281
lcd.write(1);
// рисуем символ "градус"
282
}
283
284
lcd.setCursor(8, 0);
// курсор на 8 позицию 1 строки
285
lcd.write(2);
// рисуем разделительную линию
286
287
lcd.setCursor(9, 0);
// курсор на 9 позицию 1 строки
288
289
/* Выводим значение текущей температуры и сносим лишние символы при переходе разряда показаний.
290
Должно быть пять символов отображения текущей температуры, с учетом того, что датчик сам
291
присваивает знак "-" отрицательным значениям
292
*/
293
// Если температура имеет двухзначное значение до запятой, от 10 до 99,
294
// пишем ее, добавляя знак "+", например, +36,6
295
if
((temperature >= 10)&&(temperature < 100))
296
{
297
lcd.setCursor(9, 0);
// курсор на 9 позицию 1 строки
298
lcd.print(
"+"
);
299
lcd.print(temperature, 1);
// выводим текущее значение температуры, (значение 1 - два знака после запятой)
300
lcd.setCursor(14, 0);
// курсор на 14 позицию 1 строки
301
lcd.write(1);
// рисуем символ "градус"
302
lcd.setCursor(15, 0);
// курсор на 15 позицию 1 строки
303
lcd.print(
"C"
);
304
}
305
306
// Если температура имеет отрицательное однозначное значение до запятой, от -10 до 0,
307
// пишем ее, со знаком "-", который напишет сам датчик например, -3,6
308
else
if
((temperature > -10)&&(temperature <= 0))
309
{
310
lcd.setCursor(10, 0);
// курсор на 10 позицию 1 строки
311
lcd.print(temperature, 1);
// выводим текущее значение температуры
312
lcd.setCursor(14, 0);
// курсор на 14 позицию 1 строки
313
lcd.write(1);
// рисуем символ "градус"
314
lcd.setCursor(15, 0);
// курсор на 15 позицию 1 строки
315
lcd.print(
"C"
);
316
}
317
318
// Если температура имеет положительное однозначное значение до запятой, от 0 до 10,
319
// пишем ее, со знаком "+", например, +3,6
320
else
if
((temperature < 10)&&(temperature >= 0))
321
{
322
lcd.setCursor(10, 0);
// курсор на 12 позицию 1 строки
323
lcd.print(
"+"
);
324
lcd.print(temperature, 1);
// выводим текущее значение температуры
325
lcd.setCursor(14, 0);
// курсор на 14 позицию 1 строки
326
lcd.write(1);
// рисуем символ "градус"
327
lcd.setCursor(15, 0);
// курсор на 15 позицию 1 строки
328
lcd.print(
"C"
);
329
}
330
331
// во всех остальных случаях, когда выводится пяти символьное значение:
332
// если значение температуры положительное трехзначное, например, 102,5 (знак "+" не добавляется)
333
// если значение температуры отрицательное двухзначное, например, -18,4
334
else
335
{
336
lcd.setCursor(9, 0);
// курсор на 9 позицию 1 строки
337
lcd.print(temperature, 1);
// выводим текущее значение температуры
338
lcd.setCursor(14, 0);
// курсор на 14 позицию 1 строки
339
lcd.write(1);
// рисуем символ "градус"
340
lcd.setCursor(15, 0);
// курсор на 15 позицию 1 строки
341
lcd.print(
"C"
);
342
}
343
344
/****** Пишем вторую строку дисплея ********************/
345
lcd.setCursor(0, 1);
// курсор на 0 позицию 2 строки
346
lcd.print(
"Max"
);
347
lcd.setCursor(4, 1);
// курсор на 4 позицию 2 строки
348
349
// Если верхнее пороговое значение температуры представлено двухзначным числом от 10 до 99,
350
// пишем значение, добавляя знак "+", например, +36
351
if
((tempMax >= 10)&&(tempMax < 100))
352
{
353
lcd.setCursor(4, 1);
// курсор на 4 позицию 1 строки
354
lcd.print(
"+"
);
355
lcd.print(tempMax);
// пишем верхнее пороговое значение температуры
356
lcd.write(1);
// рисуем символ "градус"
357
}
358
359
// Если верхнее пороговое значение температуры имеет отрицательное однозначное значение от -10 до 0,
360
// пишем значение, со знаком "-", который присваивается программно, например, -3
361
else
if
((tempMax > -10)&&(tempMax <= 0))
362
{
363
lcd.setCursor(4, 1);
// курсор на 4 позицию 1 строки
364
lcd.print(tempMax);
// пишем верхнее пороговое значение температуры
365
lcd.write(1);
// рисуем символ "градус"
366
}
367
368
// Если верхнее пороговое значение температуры имеет положительное однозначное значение от 0 до 10,
369
// пишем значение, добавляя знак "+", например, +6
370
else
if
((tempMax < 10)&&(tempMax >= 0))
371
{
372
lcd.setCursor(4, 1);
// курсор на 4 позицию 1 строки
373
lcd.print(
"+"
);
374
lcd.print(tempMax);
// выводим верхнее пороговое значение температуры
375
lcd.write(1);
// рисуем символ "градус"
376
}
377
378
// во всех остальных случаях, когда выводится 3-х символьное значение:
379
// если верхнее пороговое значение температуры положительное трехзначное, например, 102 (знак "+" не добавляется)
380
// если верхнее пороговое значение температуры отрицательное двухзначное, например, -18
381
else
382
{
383
lcd.setCursor(4, 1);
// курсор на 4 позицию 1 строки
384
lcd.print(tempMax);
// выводим верхнее пороговое значение температуры
385
lcd.write(1);
// рисуем символ "градус"
386
}
387
388
lcd.setCursor(8, 1);
// курсор на 8 позицию 1 строки
389
lcd.write(2);
// рисуем разделительную линию
390
391
lcd.setCursor(9,1);
// курсор на 8 позицию 2 строки
392
lcd.print(
"OUT"
);
393
lcd.setCursor(13,1);
// курсор на 8 позицию 2 строки
394
395
if
(digitalRead(OUT3))
// если получаем значение с выхода 3
396
{
397
lcd.print(
"ON "
);
// пишем состояние реле 3 "ON"
398
}
399
else
// в противном случае
400
{
401
lcd.print(
"OFF"
);
// пишем состояние реле 3 "OFF"
402
}
403
delay(100);
// пауза 0.1 секунда
404
405
406
/************* Управление R G B L E D ********************************/
407
/* устанавливаем тип переменных tempMin_led и tempMax_led для вычислений с плавающей запятой
408
и определяем их значение равное установленным пороговым значениям температур */
409
tempMin_led = (
float
)tempMin / 1.0;
410
tempMax_led = (
float
)tempMax / 1.0;
411
412
/* значение переменной delta вычисляем как положительное значение разницы пороговых температур
413
разделенное на 25 оттенков цветового спектра, подлежащего отображению RGB LED в зависимости
414
от температуры и в пределах значений заданных параметрами tempMin и tempMax
415
(с учетом того, что всегда tempMin < tempMax) */
416
delta = ((tempMax_led - tempMin_led) / 25);
// разницу температур / 25 оттенков
417
418
/* Устанавливаем уровень ШИМ сигнала на красной, зеленой и синей линиях RGB
419
в зависимости от температуры и в пределах значений заданных параметрами tempMin и tempMax
420
путем поэтапного прибавления к значению нижнего уровня температуры кратного значения delta
421
*/
422
423
if
(temperature < tempMin_led)
// при значении температуры ниже нижнего заданного значения
424
{
425
analogWrite (red, 0);
// отображается синий
426
analogWrite (green, 0);
427
analogWrite (blue, 255);
428
}
429
430
/* Четыре основных этапа изменение цвета:
431
1. От синего к голубому
432
2. От голубого к зеленому
433
3. От зеленого к желтому
434
4. От желтого к красному
435
Каждый этап состоит из 6 частей.
436
Значение ШИМ = 255 / 6 = 42.5. Округленно 42 = шаг изменения значения функции analogWrite
437
*/
438
439
// от синего к голубому
440
else
if
(temperature >= tempMin_led && temperature <= (tempMin_led + delta))
441
{
442
analogWrite (red, 0);
443
analogWrite (green, 0);
444
analogWrite (blue, 255);
445
}
446
else
if
(temperature > (tempMin_led + delta) && temperature <= (tempMin_led + (2*delta)))
447
{
448
analogWrite (red, 0);
449
analogWrite (green, 42);
450
analogWrite (blue, 255);
451
}
452
else
if
(temperature >(tempMin_led+(2*delta)) && temperature <= (tempMin_led + (3*delta)))
453
{
454
analogWrite (red, 0);
455
analogWrite (green, 85);
456
analogWrite (blue, 255);
457
}
458
else
if
(temperature > (tempMin_led + (3*delta)) && temperature <= (tempMin_led + (4*delta)))
459
{
460
analogWrite (red, 0);
461
analogWrite (green, 127);
462
analogWrite (blue, 255);
463
}
464
else
if
(temperature > (tempMin_led + (4*delta)) && temperature <= (tempMin_led + (5*delta)))
465
{
466
analogWrite (red, 0);
467
analogWrite (green, 170);
468
analogWrite (blue, 255);
469
}
470
else
if
(temperature > (tempMin_led + (5*delta)) && temperature <= (tempMin_led + (6*delta)))
471
{
472
analogWrite (red, 0);
473
analogWrite (green, 212);
474
analogWrite (blue, 255);
475
}
476
else
if
(temperature > (tempMin_led + (6*delta)) && temperature <= (tempMin_led + (7*delta)))
477
{
478
analogWrite (red, 0);
479
analogWrite (green, 255);
480
analogWrite (blue, 255);
481
}
482
483
// от голубого к зеленому
484
else
if
(temperature > (tempMin_led + (7*delta)) && temperature <= (tempMin_led + (8*delta)))
485
{
486
analogWrite (red, 0);
487
analogWrite (green, 255);
488
analogWrite (blue, 212);
489
}
490
else
if
(temperature > (tempMin_led + (8*delta)) && temperature <= (tempMin_led + (9*delta)))
491
{
492
analogWrite (red, 0);
493
analogWrite (green, 255);
494
analogWrite (blue, 170);
495
}
496
else
if
(temperature > (tempMin_led + (9*delta)) && temperature <= (tempMin_led + (10*delta)))
497
{
498
analogWrite (red, 0);
499
analogWrite (green, 255);
500
analogWrite (blue, 127);
501
}
502
else
if
(temperature > (tempMin_led + (10*delta)) && temperature <= (tempMin_led + (11*delta)))
503
{
504
analogWrite (red, 0);
505
analogWrite (green, 255);
506
analogWrite (blue, 85);
507
}
508
else
if
(temperature > (tempMin_led + (11*delta)) && temperature <= (tempMin_led + (12*delta)))
509
{
510
analogWrite (red, 0);
511
analogWrite (green, 255);
512
analogWrite (blue, 42);
513
}
514
else
if
(temperature > (tempMin_led + (12*delta)) && temperature <= (tempMin_led + (13*delta)))
515
{
516
analogWrite (red, 0);
517
analogWrite (green, 255);
518
analogWrite (blue, 0);
519
}
520
521
// от зеленого к желтому
522
else
if
(temperature > (tempMin_led + (13*delta)) && temperature <= (tempMin_led + (14*delta)))
523
{
524
analogWrite (red, 42);
525
analogWrite (green, 255);
526
analogWrite (blue, 0);
527
}
528
else
if
(temperature > (tempMin_led + (14*delta)) && temperature <= (tempMin_led + (15*delta)))
529
{
530
analogWrite (red, 85);
531
analogWrite (green, 255);
532
analogWrite (blue, 0);
533
}
534
else
if
(temperature > (tempMin_led + (15*delta)) && temperature <= (tempMin_led + (16*delta)))
535
{
536
analogWrite (red, 127);
537
analogWrite (green, 255);
538
analogWrite (blue, 0);
539
}
540
else
if
(temperature > (tempMin_led + (16*delta)) && temperature <= (tempMin_led + (17*delta)))
541
{
542
analogWrite (red, 170);
543
analogWrite (green, 255);
544
analogWrite (blue, 0);
545
}
546
else
if
(temperature > (tempMin_led + (17*delta)) && temperature <= (tempMin_led + (18*delta)))
547
{
548
analogWrite (red, 212);
549
analogWrite (green, 255);
550
analogWrite (blue, 0);
551
}
552
else
if
(temperature > (tempMin_led + (18*delta)) && temperature <= (tempMin_led + (19*delta)))
553
{
554
analogWrite (red, 255);
555
analogWrite (green, 255);
556
analogWrite (blue, 0);
557
}
558
559
// от желтого к красному
560
else
if
(temperature > (tempMin_led + (19*delta)) && temperature <= (tempMin_led + (20*delta)))
561
{
562
analogWrite (red, 255);
563
analogWrite (green, 212);
564
analogWrite (blue, 0);
565
}
566
else
if
(temperature > (tempMin_led + (20*delta)) && temperature <= (tempMin_led + (21*delta)))
567
{
568
analogWrite (red, 255);
569
analogWrite (green, 170);
570
analogWrite (blue, 0);
571
}
572
else
if
(temperature > (tempMin_led + (21*delta)) && temperature <= (tempMin_led + (22*delta)))
573
{
574
analogWrite (red, 255);
575
analogWrite (green, 127);
576
analogWrite (blue, 0);
577
}
578
else
if
(temperature > (tempMin_led + (22*delta)) && temperature <= (tempMin_led + (23*delta)))
579
{
580
analogWrite (red, 255);
581
analogWrite (green, 85);
582
analogWrite (blue, 0);
583
}
584
else
if
(temperature > (tempMin_led + (23*delta)) && temperature <= (tempMin_led + (24*delta)))
585
{
586
analogWrite (red, 255);
587
analogWrite (green, 42);
588
analogWrite (blue, 0);
589
}
590
else
if
(temperature > (tempMin_led + (24*delta)) && temperature <= (tempMin_led + (25*delta)))
591
{
592
analogWrite (red, 255);
593
analogWrite (green, 0);
594
analogWrite (blue, 0);
595
}
596
597
else
if
(temperature >= tempMax_led)
// при значении температуры выше высшего заданного значения
598
{
599
analogWrite (red, 255);
// отображается красный
600
analogWrite (green, 0);
601
analogWrite (blue, 0);
602
}
603
604
/******/
Serial
.print(
"temperature "
);
605
/******/
Serial
.println(temperature);
606
/******/
Serial
.print(
"Min "
);
607
/******/
Serial
.println(tempMin);
608
/******/
Serial
.print(
"Max "
);
609
/******/
Serial
.println(tempMax);
610
/******/
Serial
.print(
"OUT "
);
611
/******/
if
(digitalRead(OUT3)) {
Serial
.println(
"ON"
);}
612
/******/
else
{
Serial
.println(
"OFF"
);}
613
614
}
// закрываем цикл void loop
Вот теперь нормально.
Самый первый коммент, код лучше вставлять правильно , иначе очень не читабельно.
Как вы умудрились получить 205гр/С с Далласом? С EEPROM кажется намудрили, оставьте целочисленные значения и старший знаковый бит, будет -127 до 127. Если хочется больше, то двухбайтовое int. Ну и перебор значений наверно в For будет изящнее.
А так, интересненько, сам хочу нечто подобное замутить, только в виде ночника с погодной станцией.
Пока писал, уже исправились, еще сворачивать научится))))
Спасибо за первый комментарий.
Конечно, получить с Далласа 205 гр не получится, я и не пытался. Грел зажигалкой до 110. Как в бане.
С EEPROM буду дальше думать. В коде написал первое, что пришло в голову. Хотя еще не вижу пути иного решения.
А вот за идею о применении цикла for - для перебора цветов, отдельное спасибо. Если я правильно понимаю, циклов for будет четыре, аналгичо как у меня четыре блока перебора цветов от син. к гол., от гол. к зел., от зел. к желт., от желт. к красн. Если датите подсказку, тоже огромное спасибо.
В описании, я не стал вдаваться в технические подробности устройства и подробные описания его компонентов. Если кому интересно, пишите на личную почту (адрес: s-chuprin@mail.ru ), пришлю схемы, описание, фото и все остальное.
Интересно Ваше мнение по решению аналогичных задач в проекте http://ergoz.ru/electronics/arduino/rgb-led-strip-upravlyaemyiy-arduino.... в котором светодиод изменяет цвет в зависимости от диапазона температур, задаваемых в программном коде. Не понимаю, как в этом проекте происходит перебор цветов и что намудрил этот мастер. Я этот проект повторил на макетной плате. Работает, в том числе в диапазоне отрицательных значений (у меня в морозильной камере -16 гр.). Цвет RGB диода изменяется плавно без скачков. Красиво, но RGB диоды в этом проекте горят слабо, в пол силы. Тоже интересно, почему?
С епромом для однобайтовых целочисленных так:
01
#include <EEPROM.h> // подключение библиотеки внутренней памяти
02
03
float
a=-100.35;
04
char
b;
05
06
void
setup
(){
07
08
Serial
.begin(9600);
09
}
10
11
void
loop
(){
12
b=a;
13
Serial
.println(b,DEC);
14
EEPROM.write(101,b);
15
delay(2000);
16
b=EEPROM.read(101);
17
Serial
.println(b,DEC);
18
delay(1000000);
19
}
Ключевое слово "char".