
Лабораторная работа №4 (2)
.docxФедеральное государственное бюджетное образовательное учреждение
высшего профессионального образования
«Магнитогорский государственный технический университет
им. Г.И.Носова»
Кафедра ЭиМЭ
Лабораторная работа №4
по дисциплине «Arduino. Проектирование устройств»
на тему «Использование датчиков»
Вариант №3
Выполнил: студент группы
Проверил: старший преподаватель ЭиМЭ
Лымарь А. Б.
Магнитогорск, 2025
Задание 1. Оповещение температуры в помещении.
Разработать электрическую принципиальную схему и прошивку для устройства, в котором при помощи кнопок (+T и -T) будет регулироваться пределы значений температуры в помещении.
Рисунок 1 Схема.
Рисунок 2 Схема.
Программа.
#include <Adafruit_NeoPixel.h>
#define RED_PIN 2
#define GREEN_PIN 3
#define BLUE_PIN 4
#define BTN_DOWN 5
#define BTN_UP 6
#define BTN_SEL 7
#define TEMP_PIN A0
#define STEP_SIZE 4
int minTemp = 20; // Начальное значение минимальной температуры
int maxTemp = 30; // Начальное значение максимальной температуры
bool minSet = false; // Флаг, указывающий, установлен ли минимум
bool maxSet = false; // Флаг, указывающий, установлен ли максимум
void setup() {
Serial.begin(9600);
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_SEL, INPUT_PULLUP);
// Установка минимальной температуры при первом запуске
Serial.println("Set the minimum temperature:");
Serial.print("Current minimum temperature: ");
Serial.println(minTemp);
while (!minSet) {
Serial.print("minSet: "); Serial.println(minSet);
Serial.print("BTN_UP: "); Serial.println(digitalRead(BTN_UP));
Serial.print("BTN_DOWN: "); Serial.println(digitalRead(BTN_DOWN));
Serial.print("BTN_SEL: "); Serial.println(digitalRead(BTN_SEL));
if (digitalRead(BTN_UP) == LOW) {
minTemp += STEP_SIZE;
Serial.print("The minimum temperature has been increased to: ");
Serial.println(minTemp);
delay(200); // Debounce
}
if (digitalRead(BTN_DOWN) == LOW) {
minTemp -= STEP_SIZE;
Serial.print("The minimum temperature has been reduced to: ");
Serial.println(minTemp);
delay(200); // Debounce
}
if (digitalRead(BTN_SEL) == LOW) {
minSet = true;
Serial.println("The minimum temperature is set.");
delay(200); // Debounce
}
delay(50); // Небольшая задержка, чтобы Serial Monitor успел отобразить данные
}
// Установка максимальной температуры
Serial.println("Set the maximum temperature:");
Serial.print("Current maximum temperature: ");
Serial.println(maxTemp);
while (!maxSet) {
Serial.print("maxSet: "); Serial.println(maxSet);
Serial.print("BTN_UP: "); Serial.println(digitalRead(BTN_UP));
Serial.print("BTN_DOWN: "); Serial.println(digitalRead(BTN_DOWN));
Serial.print("BTN_SEL: "); Serial.println(digitalRead(BTN_SEL));
if (digitalRead(BTN_UP) == LOW) {
maxTemp += STEP_SIZE;
Serial.print("Maximum temperature increased to: ");
Serial.println(maxTemp);
delay(200); // Debounce
}
if (digitalRead(BTN_DOWN) == LOW) {
maxTemp -= STEP_SIZE;
Serial.print("The maximum temperature has been reduced to: ");
Serial.println(maxTemp);
delay(200); // Debounce
}
if (digitalRead(BTN_SEL) == LOW) {
maxSet = true;
Serial.println("The maximum temperature is set.");
delay(200); // Debounce
}
delay(50); // Небольшая задержка, чтобы Serial Monitor успел отобразить данные
}
Serial.println("Getting started...");
Serial.print("Minimum temperature: ");
Serial.println(minTemp);
Serial.print("Maximum temperature: ");
Serial.println(maxTemp);
}
void loop() {
// Считываем температуру с датчика TMP36
int sensorValue = analogRead(TEMP_PIN);
float voltage = sensorValue * (5.0 / 1023.0); // Convert to voltage
float temperatureC = (voltage - 0.5) * 100; // Convert to Celsius
//float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; // Optionally Convert to Fahrenheit
// Выводим текущую температуру в монитор порта
Serial.print("Sensor Value: "); Serial.println(sensorValue); // Выводим "сырое" значение
Serial.print("Current temperature: ");
Serial.print(temperatureC);
Serial.println(" °C");
//Определение цвета для светодиода
int red = 0;
int green = 0;
int blue = 0;
if (temperatureC <= minTemp) {
blue = 255;
//Моргание синим
for (int i = 0; i < 5; i++) {
setColor(0, 0, 255);
delay(200);
setColor(0, 0, 0);
delay(200);
}
} else if (temperatureC >= maxTemp) {
red = 255;
//Моргание красным
for (int i = 0; i < 5; i++) {
setColor(255, 0, 0);
delay(200);
setColor(0, 0, 0);
delay(200);
}
} else {
// Градиент от синего к красному
float ratio = (temperatureC - minTemp) / (maxTemp - minTemp);
red = (int)(255 * ratio);
blue = 255 - red; // Чтобы зеленый не горел, а градиент был между синим и красным
green = 0; // Отключаем зелёный
}
// Устанавливаем цвет RGB-светодиода
setColor(red, green, blue);
delay(1000); // Пауза перед следующим измерением
// Проверка нажатия кнопок (можно добавить управление в процессе работы, если нужно)
/* if (digitalRead(BTN_UP) == LOW) {
Serial.println("Кнопка UP нажата (действия не определены).");
delay(200);
}
if (digitalRead(BTN_DOWN) == LOW) {
Serial.println("Кнопка DOWN нажата (действия не определены).");
delay(200);
}
if (digitalRead(BTN_SEL) == LOW) {
Serial.println("Кнопка SELECT нажата (действия не определены).");
delay(200);
}*/
}
// Функция для установки цвета RGB-светодиода
void setColor(int red, int green, int blue) {
analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);
}
Задание 2. Контроллёр расстояния.
Разработать электрическую принципиальную схему и прошивку для устройства, в котором при помощи потенциометра будет регулироваться расстояние срабатывания лампы, подключаемой через реле.
Выполнение.
Рисунок 3 Схема.
Программа.
#define TRIG_PIN 4 // Trig пин HC-SR04
#define ECHO_PIN 5 // Echo пин HC-SR04
#define POT_PIN 3 // Пин потенциометра
#define SELECT_PIN A0 // Пин кнопки SELECT
#define LED_PIN 2 // Пин светодиода
// Константы
#define MIN_DISTANCE 100 // Нижний предел расстояния (см)
#define MAX_DISTANCE 200 // Верхний предел расстояния (см)
#define ERROR_BLINK_RATE 500 // Частота мигания при ошибке (мс)
// Переменные
int setDistance; // Установленное расстояние с потенциометра
float currentDistance; // Текущее измеренное расстояние
bool distanceSet = false; // Флаг, указывающий, установлено ли расстояние
bool errorCondition = false;
// Функция для измерения расстояния (HC-SR04)
float measureDistance() {
// Очистка пина TRIG
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
// Подача сигнала TRIG на 10 микросекунд
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Измерение длительности сигнала ECHO
long duration = pulseIn(ECHO_PIN, HIGH);
// Вычисление расстояния в сантиметрах
float distance = duration * 0.034 / 2;
return distance;
}
void setup() {
Serial.begin(9600);
// Настройка пинов
pinMode(POT_PIN, INPUT);
pinMode(SELECT_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
// Настройка пинов для HC-SR04
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
Serial.println("Ready");
}
void loop() {
// Чтение значения потенциометра
int potValue = analogRead(POT_PIN);
// Преобразование значения потенциометра в расстояние (см)
// Ограничение расстояния в пределах MIN_DISTANCE и MAX_DISTANCE
setDistance = map(potValue, 0, 1023, MIN_DISTANCE, MAX_DISTANCE);
// Измерение расстояния до объекта (закомментируйте один из вариантов)
currentDistance = measureDistance(); // Используйте эту строку для HC-SR04
// currentDistance = readSharpIR(); // Используйте эту строку для Sharp IR
// Вывод данных в Serial Monitor
Serial.print("Set Distance: ");
Serial.print(setDistance);
Serial.print(" cm, Current Distance: ");
Serial.print(currentDistance);
Serial.println(" cm");
// Обработка кнопки SELECT
if (digitalRead(SELECT_PIN) == LOW) {
delay(50); // Debounce
if (digitalRead(SELECT_PIN) == LOW) {
distanceSet = !distanceSet; // Инверсия флага
Serial.print("Distance setting is now: ");
Serial.println(distanceSet ? "ON" : "OFF");
while (digitalRead(SELECT_PIN) == LOW) delay(1);
}
}
// Обработка условий ошибки
if (currentDistance > MAX_DISTANCE || currentDistance < MIN_DISTANCE || isnan(currentDistance)) {
errorCondition = true;
} else {
errorCondition = false;
}
// Управление лампой и индикация ошибок
if (distanceSet) {
if (!errorCondition && currentDistance <= setDistance) {
digitalWrite(LED_PIN, HIGH); // Включить светодиод
} else {
digitalWrite(LED_PIN, LOW); // Выключить светодиод
}
} else {
digitalWrite(LED_PIN, LOW);
}
// Мигание светодиода при ошибке
if (errorCondition) {
digitalWrite(LED_PIN, millis() % 1000 < ERROR_BLINK_RATE ? HIGH : LOW);
}
delay(100);
}