Декоративный термометр на микроконтроллере

В этой статье речь пойдет об устройстве, которое в целом не будет решать сложные задачи, управлять механизмами и так далее. Речь пойдет об своеобразном сувенире, «безделушке».

Собственно устройство представляет собой термометр. Но есть несколько нюансов, которые и делают его больше сувениром, чем прибором с конкретным назначением: точность измерения условна — данные о температуре отображаются лишь приблизительно, в качестве «индикатора», дисплея, выступает светодиодная «полоска». Что же касается точности, то как вы поняли, она не особо нужна, но тем не менее имеется возможность использования высокоточного датчика температуры. 

Закончив с вводной частью можно заняться разбором схемы. Основа всей конструкции — микроконтроллер ATmega8. Почему именно он? В его пользу можно отнести такие факторы: 8Кб памяти, большое кол-во выводов, наличие АЦП. Из всем микроконтроллеров, находившихся у меня в наличии лишь он подходил по параметрам.

Как уже упоминалось выше, в устройстве может быть использован высокоточный датчик — DS18B20. Но так же, в случае его отсутствия можно обойтись и обыкновенным термистором. Индикация осуществляется посредством 12 светодиодов (в моем случае желтого цвета свечения). Собственно кроме перечисленных деталей понадобится ещё стабилизатор напряжения 5В — 78L05 (если вы планируете запитывать схему от USB порта или другого источника с напряжением 5В, то соответственно необходимость в нем отпадает), пара конденсаторов ёмкостью 100нФ, резисторы ограничения тока для светодиодов (смотря какие светодиоды вы будете использовать, ведь в smd исполнении микроконтроллер ATmega8 имеет меньшую рассеиваемую мощность, нежели в DIP), обвязки АЦП и датчика DS18B20 (выбор датчика осуществляется джампером: включен — термистор, отключен — DS18B20). Ниже представлена схема устройства:


Рис. 1. (схема)

Светодиоды подключаются к портам D(4-7) и B(0-8) микроконтроллера. первый светодиод подключается к PORTD4, второй — PORTD3 и т.д. Пятый светодиод подключается к PORTB0, шестой — PORTB1 и т.д.

Что касается платы — она односторонняя. Разводка платы проста и ее вполне можно повторить без использования ЛУТа (фоторезиста). К примеру, я разводил плату с помощью лака и шприца. Монтаж односторонний (все элементы располагаются с одной стороны платы). Его порядок следующий: паяется микроконтроллер, далее резисторы, разъемы (если вы будете их использовать), датчик(и) и провода к светодиодам.


Рис. 2. (Печатная плата)

Теперь о программной части. Прошивка для микроконтроллера написана в среде mikroPascal for AVR (v 6.00). Текст программы приведен ниже:

program DecorateTempMega8;

uses AADL;

var syscount: integer; //счетчики
pwmcount, maxled, pos, mode: byte;
pwm: array [0..11] of byte; //pwm «конфигуратор»
temp: integer;
tempr: real;

const a = 0.001129148; //константы для расчета
const b = 0.000234125;
const c = 0.0000000876741;

procedure PwmConf;
var i: byte;
begin
if temp > 30 then
maxled := 12
else if temp > 20 then
maxled := 10
else if temp > 10 then
maxled := 8
else if temp > 0 then
maxled := 6
else if temp <= 0 then
maxled := 4;
//////////////////////////////////
for i := 0 to maxled — 1 do
pwm[i] := 20;
if maxled — 1 < 11 then
for i := maxled to 11 do
pwm[i] := 0;
//////////////////////////////////
if pos + 1 < maxled then
pwm[pos + 1] := 50;
if pos — 1 >= 0 then
pwm[pos — 1] := 50;
if pos < maxled then
pwm[pos] := 99;
if pos < maxled then inc(pos) else pos := 0;
end;

procedure RTemp(mode: byte);
var adl, adh: byte;
begin
TCCR0 := $0;
if mode = 0 then begin //чтение с датчика ds18b20
ow_reset(PORTC, 1);
ow_write(PORTC, 1, $CC);
ow_write(PORTC, 1, $44);
delay_ms(750);
ow_reset(PORTC, 1);
ow_write(PORTC, 1, $CC);
ow_write(PORTC, 1, $BE);
delay_us(120);
adl := ow_read(PORTC, 1);
adh := ow_read(PORTC, 1);
temp := ((adh shl 8) + adl) shr 4;
if temp > 1000 then temp := — (4096 — temp);
end else if mode = 1 then begin //чтение АЦП
tempr := ADC_Read(0);
tempr := log((10240000/tempr) — 10000);
tempr := 1 / (a + (b * tempr) + (c * tempr * tempr * tempr));
temp := tempr — 273.15;
end;
TCCR0 := $1;
end;

procedure T0(); iv IVT_ADDR_TIMER0_OVF; ics ICS_AUTO;
var i, n: byte;
begin
TCCR0 := $0;
if syscount > 1000 then begin
PwmConf;
syscount := 0;
end else inc(syscount);
for i := 0 to 3 do
if pwmcount <= pwm[i] then PORTD.(i + 4) := 0 else PORTD.(i + 4) := 1;
for n := 0 to 7 do
if pwmcount <= pwm[n + 4] then PORTB.(n) := 0 else PORTB.(n) := 1;
if pwmcount < 100 then inc(pwmcount) else pwmcount := 0;
TCCR0 := $1;
end;

begin
TCCR0 := $1;
TIMSK := $1;
SREG_I_bit := 1;

DDRB := $FF;
PORTB := $FF;
DDC2_bit := 0;
DDC3_bit := 1;
DDC4_bit := 1;
PORTC2_bit := 1;
DDRD := $FC;
PORTD := $FC;

if PINC2_bit = 0 then mode := 1 else mode := 0; //проверка состояния джампера

ADC_Init;
while TRUE do begin
if mode = 1 then
delay_ms(500)
else delay_ms(10000);
RTemp(mode);
end;
end.

Алгоритм прост:

————————————————————————————-

/прерывание по таймеру/

——-

-старт

-проверка положения джампера, сохранение в переменную

-бесконечный цикл

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

-если выбран термистор, пауза 500 мс, если ds18b20 — 10000 мс

-процедура преобразования температуры

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

————————————————————————————-

Приведенное выше «каркас». Кроме основного цикла, выполняется прерывание по переполнению таймера T0. Это переполнение происходит каждые 0.000032 с (32 кГц). Но потому что для создания программного ШИМа приходится делить эту частоту на 100, то получается всего 32 Гц, но визуально это не заметно. Изначально, планировалось просто включать светодиоды до необходимой отметки на «шкале». Для такого варианта не нужен был ШИМ и программа была бы «детской». Но желание добавить каких — то эффектов одержало верх и как результат — усложнение программы. Суть же эффекта проста: светодиоды, которые «попадают» в поле «засвета» включаются на 20%, остальные, до которых температура «не доходит» — 1%, их свечения не видно.


Рис. 3. (свет 20%)

Вот среди этих 20% светодиодов и «курсирует» «бегущий огонь». 


Рис. 4. (бег. огонь) 

*Внимание! Мной использовался Proteus версии 8.1! В более старых (насчет 8.0 не знаю), например 7.7, проект не откроется!
**В архиве две версии печатной платы: для ATmega8 в smd исполнении или DIP.

В заключение, предлагаю вашему вниманию фото устройства, начиная со стадии разработки и кончая готовым экземпляром.

 


Список радиоэлементовОбозначение
Тип
Номинал
Количество
ПримечаниеМагазинМой блокнот

U1
МК AVR 8-битATmega81
smdU2
Линейный регуляторL78L051
U3
Датчик температурыDS18B201
R1
Резистор10 кОм1
ПрезиционныйR2
Резистор4.7 кОм1
0805RT1
Термистор10 кОм1
C1, C2
Конденсатор100 нФ2
0805D1-D12
СветодиодЖелтый12
Добавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Добавить комментарий

Ваш адрес email не будет опубликован.