Изобретение электронного термометра на Arduino | Статья в журнале «Юный ученый»

Отправьте статью сегодня! Журнал выйдет 26 октября, печатный экземпляр отправим 30 октября.

Опубликовать статью в журнале

Автор:

Научный руководитель:

Отличный выбор методов исследования Отличные иллюстрации Высокая практическая значимость Высокая теоретическая значимость

Рубрика: Информатика

Опубликовано в Юный учёный №7 (81) июль 2024 г.

Дата публикации: 19.06.2024

Статья просмотрена: 87 раз

Библиографическое описание:

Бухарцев, А. Д. Изобретение электронного термометра на Arduino / А. Д. Бухарцев, И. В. Зименко. — Текст : непосредственный // Юный ученый. — 2024. — № 7 (81). — С. 24-34. — URL: https://moluch.ru/young/archive/81/4573/ (дата обращения: 17.10.2024).



В статье автор рассказывает об изобретении электронного термометра.

Ключевые слова: термометр, Arduino Nano, схема подключения, Энкодер, авторское изобретение.

Каждый день людям надо измерять температуру чего-либо: тела, воды, еды, поверхности, да даже просто воздуха. Для каждого перечисленного объекта измерения требуется свой измерительный прибор. А если использовать один единый универсальный прибор, который имеет большой диапазон температуры, компактный и практичный? Это же намного удобнее и выгоднее. К сожалению, таких готовых термометров я не нашел. Поискав аналоги среди самодельных устройств, я понял, что эта тема не сильно развита, в сети много одинаковых, очень простых и незавершенных проектов.

Заинтересовавшись этой темой, я решил создать свой собственный электронный термометр, который подходил бы под все мои потребности и запросы, а также пригодился бы моей семье

Вдобавок к этому, мне очень нравится работать с электроникой (из нее можно сделать много интересных и полезных вещей), изобретать различные вещи и паять.

Итак, цель определена, я делаю самодельный термометр для измерения всего.

Технология изготовления термометра:

— нарисовать схему подключения;

— подобрать необходимые материалы;

— приобрести необходимые материалы;

— собрать схему на макетной плате;

— написать программу для термометра;

— загрузить и проверить работу программы;

— собрать всё в корпус;

— проверить работу готового изделия;

— подсчитать стоимость потраченного материала;

Изделие, которое я решил создать, должно быть функциональным, качественным и автономным.

Корпус будет сделан из ABS пластика, потому что он легок в обработке, он стойкий к низким и высоким температурам, а также такие готовые коробки 100x60x25(ДxШxВ) продаются по недорогой цене.

Данное творчество требует усидчивости, упорства, что важно кроме самого материала и инструмента.

Для изготовления понадобятся инструменты:

— Дрель-шуруповерт

— Паяльник

— Линейка

— Бормашина

— Скальпель или модельный нож

— Клеевой пистолет

Расходные материалы:

— Сверла

— Фрезы

— Флюс

— Припой

— Провода

— Термоусадка

— Стержни для клеевого пистолета

Материалы:

— ABS коробка 100x60x25

— Arduino Nano

— Энкодер

— 7-сегментный 4-значный белый дисплей на сдвиговом регистре TM1637

— Аккумулятор типа 14500 на 1А/ч

— Отсек для аккумулятора

— Термистор 10к 3950

— Разъём для термистора

— Buzzer

— Транзистор IRF 3205 (или аналог)

— Резисторы на 100 Ом и 10 кОм

— USB ASP (ICSP программатор)

— Плата зарядки аккумулятора на TP4056

— Микро повышающий модуль до 5 вольт

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

Технологическая карта.

Нарисовать схему подключения (рис.1) — Fritzing

Запрограммировать Arduino Nano — USB ASP

Спаять схему — Паяльник, припой, флюс

Подготовить корпус (вырезать необходимые отверстия) — Шуруповерт, бормашина, скальпель, линейка

Сборка схемы в корпус (рис.2) — Клеевой пистолет

Схема подключения

Рис. 1 Схема подключения

Сборка в корпус

Рис. 2 Сборка в корпус

Прилагаю код программы, написанную для данного термометра.

код программы

/**********НАСТРОЙКИ**********/

#define S1 4 //Пин S1 энкодера

#define S2 3 //Пин S2 энкодера

#define KEY 2 //Пин KEY энкодера (! ТОЛЬКО 2 ИЛИ 3 ДЛЯ ATMega328P !)

#define EB_HOLD_TIME 1000 //Сколько надо удерживать кнопку энкодера, чтобы она считалась удержанной (в мс)

#define BUZZ 5 //Пин пищалки

#define BUZZ_TYPE 0 //Тип пищалки: 0 - пассивная; 1 - активная

#define HZ 1000 //Частота для пассивной пищалки (в герцах)

#define NTC A0 //Аналоговый пин NTC термистора

#define DSP 13 //Пин питания дисплея

#define CLK 11 //Пин CLK дисплея

#define DIO 12 //Пин DIO дисплея

#define SLP_TIME 60 //Время ухода в режим сна(секунды)

#define MIDDLE 2 //Фильтрация: 0 - отсутствует, 1 - усреднение библиотеки, 2 - экспоненциальное скользящее среднее, 3 - среднее арифметическое

#define AVERAGE 40 //Кол-во усреднений для среднего арифметического

/**********НАСТРОЙКИ**********/

/**********millis() и delay()**********/

//#define millis() millis() * 2 //Для корректной работы millis

//#define delay(x) delay(x / 2) //Для корректной работы delay

/**********millis() и delay()**********/

/**********БИБЛИОТЕКИ**********/

#include

#include

#include

#include

#include

#include

GyverNTC ntc(NTC, 10000, 3950);

EncButton enc(S1, S2, KEY);

EndTM1637 disp(CLK, DIO);

/**********БИБЛИОТЕКИ**********/

/**********ПЕРЕМЕННЫЕ**********/

bool slp, ton;

volatile bool icr, stat;

byte hih = eeprom_read_byte(4), mode, tks;

float lst = eeprom_read_float(0), vcc_const, nov, vcc, nvcc;

uint32_t tmr2, tmrslp, btmr;

/**********ПЕРЕМЕННЫЕ**********/

/**********SETUP**********/

void setup() {

power.autoCalibrate();

//power.setSystemPrescaler(PRESCALER_2);

power.setSleepMode(POWERDOWN_SLEEP);

power.hardwareDisable(PWR_SPI | PWR_I2C | PWR_UART0);

attachInterrupt(digitalPinToInterrupt(KEY), isr, FALLING);

Timer1.setPeriod(60);

Timer1.enableISR();

disp.setBright(hih);

mode = 1;

pinMode(BUZZ, OUTPUT); //Пищалка

pinMode(DSP, OUTPUT);

disp.clear();

if (enc.pressing()) {

for (byte i = 0; i <= 8; i += 4) eeprom_update_dword(i, 0);

digitalWrite(DSP, 1);

enc.clear();

eeprom_update_float(5, 1.1);

vcc_const = 1.1;

disp.setBytes(_C, _A, _L, _b);

delay(1000);

vcc = readVcc();

disp.manualFloat(vcc, 2);

while (!enc.hold()) calibration();

vcc_const = (float)1.1 * vcc / readVcc();

eeprom_update_float(5, vcc_const);

disp.clear();

byte nc[11] = {_U, _c, _c, _empty, _C, _O, _n, _S, _t, _empty, _defis};

disp.runningString(nc, sizeof(nc), 300);

disp.manualFloat(vcc_const, 3);

delay(1000);

disp.setBytes(_d, _O, _n, _E);

enc.clear();

tmr2 = millis() - 4000;

} else {

vcc_const = eeprom_read_float(5);

}

readVcc();

nvcc = readVcc();

tmrslp = millis();

}

/**********SETUP**********/

/**********WAKE UP**********/

void isr() {

if (stat == 1) {

stat = 0;

icr = 1;

}

}

/**********WAKE UP**********/

/**********LOOP**********/

void loop() {

if (enc.right()) {

if (++mode > 4) mode = 1;

tmr2 = millis();

digitalWrite(DSP, 1);

delay(1);

mod(mode);

slp = 1;

tmrslp = millis();

}

if (enc.left()) {

if (--mode < 1) mode = 4;

tmr2 = millis();

digitalWrite(DSP, 1);

delay(1);

mod(mode);

slp = 1;

tmrslp = millis();

}

if (mode == 1) {

if (enc.hold()) {

uint32_t tmr = millis();

uint32_t tmr1 = millis();

bool bye = 0;

digitalWrite(BUZZ, 0);

noTone(BUZZ);

digitalWrite(DSP, 1);

delay(1);

disp.clear();

while (millis() - tmr < 180000) {

if (millis() - tmr1 > 200) {

nov = temp();

disp.manualFloat(nov);

tmr1 = millis();

}

if (enc.hold()) {

bye = 1;

break;

}

}

lst = nov;

eeprom_update_float(0, lst);

bool byze = 0;

uint32_t tmr5 = millis();

while (bye == 0) {

if (millis() - tmr5 > 400) {

if (BUZZ_TYPE == 1) {

digitalWrite(BUZZ, !digitalRead(BUZZ));

}

if (BUZZ_TYPE == 0) {

byze = !byze;

(byze == 1) ? (tone(BUZZ, HZ)) : (noTone(BUZZ));

}

tmr5 = millis();

}

if (enc.hold()) {

bye = 1;

break;

}

}

digitalWrite(BUZZ, 0);

noTone(BUZZ);

disp.clear();

enc.clear();

tmr2 = millis();

btmr = millis();

tks = 0;

ton = 0;

tmrslp = millis();

slp = 1;

}

}

if (mode == 2) {

if (enc.hold()) {

digitalWrite(DSP, 1);

delay(1);

disp.clear();

disp.manualFloat(lst);

enc.clear();

tmr2 = millis();

tmrslp = millis();

slp = 1;

}

}

if (mode == 3) {

if (enc.rightH()) {

digitalWrite(DSP, 1);

delay(1);

if (++hih > 7) hih = 0;

disp.setBright(hih);

disp.displayInts(hih);

eeprom_update_byte(4, hih);

tmr2 = millis();

tmrslp = millis();

slp = 1;

}

if (enc.leftH()) {

digitalWrite(DSP, 1);

delay(1);

if (--hih >= 250) hih = 7;

disp.setBright(hih);

disp.displayInts(hih);

eeprom_update_byte(4, hih);

tmr2 = millis();

tmrslp = millis();

slp = 1;

}

}

if (mode == 4) {

if (enc.hold()) {

digitalWrite(DSP, 1);

delay(1);

disp.clear();

nvcc = readVcc();

disp.manualFloat(nvcc, 2);

enc.clear();

tmr2 = millis();

tmrslp = millis();

slp = 1;

}

}

if (millis() - tmr2 > 5000) {

digitalWrite(DSP, 1);

delay(1);

disp.clear();

if (slp == 1) {

slp = 0;

tmrslp = millis();

}

}

if ((millis() - tmrslp) / 1000 >= SLP_TIME) {

digitalWrite(BUZZ, 0);

noTone(BUZZ);

digitalWrite(DSP, 1);

delay(1);

stat = 1;

disp.setBytes(_empty, _b, _y, _E);

delay(1000);

disp.clear();

digitalWrite(DSP, 0);

power.hardwareDisable(PWR_TIMER2);

delay(100);

power.sleep(SLEEP_FOREVER);

}

if (nvcc <= 3.0 && millis() - btmr >= 20000) {

static uint32_t btmr2 = millis();

byte cl = 0;

if (nvcc <= 3.0 && nvcc >= 2.85) cl = 1;

else if (nvcc < 2.85 && nvcc >= 2.7) cl = 2;

else cl = 3;

if (millis() - btmr2 >= 300) {

btmr2 = millis();

ton = !ton;

if (BUZZ_TYPE == 1) {

digitalWrite(BUZZ, ton);

}

if (BUZZ_TYPE == 0) {

(ton == 1) ? (tone(BUZZ, HZ)) : (noTone(BUZZ));

}

if (ton) tks++;

if (tks == cl && !ton) {

tks = 0;

btmr = millis();

nvcc = readVcc();

}

}

}

if (icr == 1) {

power.hardwareEnable(PWR_TIMER2);

digitalWrite(DSP, 1);

delay(1);

icr = 0;

disp.setBytes(_empty, _empty, _h, _i);

tmrslp = millis();

readVcc();

nvcc = readVcc();

btmr = millis();

tks = 0;

ton = 0;

slp = 1;

mode = 1;

tmr2 = millis() - 4000;

}

}

/**********LOOP**********/

/**********ВЫВОД РЕЖИМА**********/

void mod(byte m) {

switch (m) {

case 1: {

disp.setBytes(_t, _E, _S, _t);

break;

}

case 2: {

disp.setBytes(_L, _A, _S, _t);

break;

}

case 3: {

disp.setBytes(_L, _i, _G, _t);

break;

}

case 4: {

disp.setBytes(_b, _A, _t, _t);

break;

}

}

}

/**********ВЫВОД РЕЖИМА**********/

/**********ФИЛЬТРАЦИЯ**********/

float temp() {

float out = 0.0;

switch (MIDDLE) {

case 0: out = ntc.getTemp(); break;

case 1: out = ntc.getTempAverage(); break;

case 2: {

static float filT = 0;

filT += (ntc.getTempAverage() - filT) * 0.1;

out = filT;

}

break;

case 3: {

long aver = 0;

for (int i = 0; i < AVERAGE; i++) aver += ntc.getTempAverage() * 10;

aver /= AVERAGE;

out = (float)aver / 10;

}

break;

}

return out;

}

/**********ФИЛЬТРАЦИЯ**********/

/**********КАЛИБРОВКА**********/

void calibration() {

if (enc.right()) {

vcc += 0.01;

disp.manualFloat(vcc, 2);

}

if (enc.left()) {

vcc -= 0.01;

disp.manualFloat(vcc, 2);

}

}

/**********КАЛИБРОВКА**********/

/**********ИЗМЕРЕНИЕ НАПРЯЖЕНИЯ**********/

float readVcc() {

ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);

delay(2); // Wait for Vref to settle

ADCSRA |= _BV(ADSC); // Start conversion

while (bit_is_set(ADCSRA, ADSC)); // measuring

uint8_t low = ADCL; // must read ADCL first - it then locks ADCH

uint8_t high = ADCH; // unlocks both

long result = (high << 8) | low;

result = vcc_const * 1023 * 1000 / result; // расчёт реального VCC

return result / 1000.0; // возвращает VCC

}

/**********ИЗМЕРЕНИЕ НАПРЯЖЕНИЯ**********/

/**********tick ЭНКОДЕРА**********/

ISR(TIMER1_A) {

enc.tick();

}

/**********tick ЭНКОДЕРА**********/

Также в данном проекте используется моя библиотека для дисплея, которую я выложил на сайт https://github.com/EndLibs/EndTM1637 (я периодически пишу и выкладываю библиотеки для разных датчиков).

Мною рассчитано, что на одном заряде термометр проработает год.

Кратное описание функций термометра:

1) поворотами энкодера можно перемещаться по пунктам меню. После минуты бездействия, термометр перейдет в режим сна, показав на дисплее «bye».

2) выйти из режима сна можно нажатием на кнопку энкодера (на дисплее будет показано «hi»), а пункт меню будет изменен на (temp).

3) в меню есть 4 пункта — temp (тест температуры), last (последняя температура), ligt (яркость дисплея), batt (напряжение аккумулятора).

4) тест температуры («temp») — при удержании кнопки энкодера, начнется тест температуры, при котором на дисплее будет показываться текущая температура. Если ничего не делать, то тест прекратится через три минуты, издавая писк, и показывая последнюю измеренную температуру. Чтобы выключить писк, надо удержать кнопку энкодера. Если во время теста удержать кнопку энкодера, то тест прекратится, а писка не будет.

5) последняя температура («last») — при удержании кнопки энкодера, на дисплее 5 секунд будет показываться последняя температура.

6) яркость дисплея («ligt») — если при нажатой кнопке энкодера его вращать, то яркость дисплея будет меняться от 0 до 7, при этом на дисплее будет показываться уровень яркости.

7) напряжение аккумулятора («batt») — при удержании кнопки энкодера, на дисплее будет показано напряжение аккумулятора на 5 секунд.

8) если при включении зажать кнопку энкодера, то термометр перейдет в режим калибровки, одновременно очистив данные о последней температуре и яркости дисплея. На дисплее на секунду будет показано «calb», после будет показано измеренное напряжение аккумулятора. Вращением энкодера надо сопоставить его с реальным напряжением аккумулятора, которое надо изменить вручную. После надо удержать энкодер. На дисплее будет показана константа напряжения и надпись «done».

9) все настройки сохраняются в энергонезависимую помять.

10) если заряд аккумулятора от 20 до 30 процентов, то термометр будет издавать 1 писк, раз в 20 секунд. Если заряд аккумулятора от 10 до 20 процентов, то термометр будет издавать 2 писка, раз в 20 секунд. Если заряд аккумулятора менее 10 процентов, то термометр будет издавать 3 писка раз в 20 секунд.

Диапазон измеряемой температуры от -40°С до +125°С.

Данный термометр (рис. 3) можно назвать универсальным и многофункциональным. В нем есть настраиваемое ограничение по времени для измерения температуры, что полезно для бытового использования. Также есть возможность просмотреть измеренные температуры. Для вывода различных показаний стоит яркий дисплей, который видно даже на солнце, яркость дисплея можно регулировать для комфортной работы в темноте. А для экономии на батарейках внутри стоит аккумулятор, за его напряжение можно следить на дисплее (напряжение можно откалибровать), если он будет почти разряжен, то электроника будет напоминать писком. Если надо срочно что-то измерить, а аккумулятор разрядился и прибор не работает (внутри стоит плата защиты-зарядки, которая отключает аккумулятор при разрядке), то можно его достать и поменять, а свободный — поставить на зарядку. Благодаря удобной эргономике, термометром можно управлять одной рукой. Под универсальностью я имел в виду то, что в термометр можно вставлять разные по форме датчики температуры (термисторы) для разной по назначению работы. А учитывая, что внутри стоит система энергосбережения, термометр на одном заряде проработает 1 год. Также не стоит забывать о бюджетности — из-за того, что используются дешевые модули, цена небольшая для такого количества задач.

Электронный термометр

Рис. 3. Электронный термометр

Так как термометр создан на основе Arduino Nano, его можно постоянно совершенствовать, добавляя новые датчики и функции. Данный проект был создан для участия в региональном этапе ВСОШ Ростовской области в 2023/2024 уч.году.

Литература:

  1. Технология: 8–9 классы: учебник / Е. С. Глозман, О. А. Кожина, Ю. Л. Хотунцев и др. — 2-е изд., стереотип. — М.: Просвещение, 2021. — 380, [4] с.: ил.
  2. https://alexgyver.ru/lessons/
  3. https://kit.alexgyver.ru/tutorials/


Ключевые слова

термометр, энкодер, схема подключения, Arduino Nano, авторское изобретение

Похожие статьи

Разработка автономного робота на базе Arduino Uno для создания изображений

В статье описывается процесс создания автономного робота-рисовальщика для создания сложных изображений.

Управление железнодорожным переездом

В данной статье рассмотрена модель управления железнодорожным переездом. Результатом является разработка электрической принципиальной схемы микропроцессорного устройства на аппаратной платформе Arduino Uno R3, в основе которой лежит датчик расстояния...

Автоматизация передвижения тяжелой мебели

В статье автор рассказывает, как усовершенствовать процедуру уборки под диваном (тяжелой мебелью), вмонтировав при производстве в ножки дивана выдвижные колеса на основе Arduino Nano.

Особенности программирования микроконтроллера GPS-модуля A9G

В статье автор рассматривает особенности программирования модуля Ai-Thinker A9G для работы в качестве GPS датчика для автономных навигационных систем.

Проект эко-гаджета Climate Processing

В статье рассмотрены предпосылки и этапы создания проекта эко-гаджета в сфере Хелснет (HealthNet) НТИ. Проект представляет приспособление для создания микроклимата в помещении с использованием технологии аквапоника.

Место и роль искусственного интеллекта на уроках математики

Исследование возможностей робототехники в медицине

Целью работы является создание роботизированной руки, которая способна оказывать помощь в медицине.

Управление светодиодом Arduino UNO через среду LabVIEW

В данной статье рассматривается плата Arduino UNO среда LabVIEW, приводится программная часть реализации загорания светодиода на плате Arduino UNO с помощью управления кнопкой в среде LabVIEW.

Автономное управление чайником

В статье обобщается практический опыт по разработке и изготовлению устройста автоматизации включения и выключения электрического прибора (поттера) в зависимости от уровня освещения в помещении. Описана актуальность созданного проекта, поставленная за...

От школьных уроков до создания конструктора

В своей статье авторы описывают опыт создания программируемого конструктора «Лифт 2.0», поддержанного Красноярским краевым фондом науки, а также рассматривают аспекты развития робототехники в школьном образовании.

Похожие статьи

Разработка автономного робота на базе Arduino Uno для создания изображений

В статье описывается процесс создания автономного робота-рисовальщика для создания сложных изображений.

Управление железнодорожным переездом

В данной статье рассмотрена модель управления железнодорожным переездом. Результатом является разработка электрической принципиальной схемы микропроцессорного устройства на аппаратной платформе Arduino Uno R3, в основе которой лежит датчик расстояния...

Автоматизация передвижения тяжелой мебели

В статье автор рассказывает, как усовершенствовать процедуру уборки под диваном (тяжелой мебелью), вмонтировав при производстве в ножки дивана выдвижные колеса на основе Arduino Nano.

Особенности программирования микроконтроллера GPS-модуля A9G

В статье автор рассматривает особенности программирования модуля Ai-Thinker A9G для работы в качестве GPS датчика для автономных навигационных систем.

Проект эко-гаджета Climate Processing

В статье рассмотрены предпосылки и этапы создания проекта эко-гаджета в сфере Хелснет (HealthNet) НТИ. Проект представляет приспособление для создания микроклимата в помещении с использованием технологии аквапоника.

Место и роль искусственного интеллекта на уроках математики

Исследование возможностей робототехники в медицине

Целью работы является создание роботизированной руки, которая способна оказывать помощь в медицине.

Управление светодиодом Arduino UNO через среду LabVIEW

В данной статье рассматривается плата Arduino UNO среда LabVIEW, приводится программная часть реализации загорания светодиода на плате Arduino UNO с помощью управления кнопкой в среде LabVIEW.

Автономное управление чайником

В статье обобщается практический опыт по разработке и изготовлению устройста автоматизации включения и выключения электрического прибора (поттера) в зависимости от уровня освещения в помещении. Описана актуальность созданного проекта, поставленная за...

От школьных уроков до создания конструктора

В своей статье авторы описывают опыт создания программируемого конструктора «Лифт 2.0», поддержанного Красноярским краевым фондом науки, а также рассматривают аспекты развития робототехники в школьном образовании.

Задать вопрос