Давно подмечено, что экспериментируя с умным домом, люди в первую очередь стремятся автоматизировать включение освещения. Иногда для этих целей подходит датчик движения (объемный или PIR или инфракрасный), но я на своем опыте убедился, что у него есть ряд недостатков. Datasheet датчика пишет, что он точно определяет человека в поле зрения 5 метров. Однако в моём случае, даже при выкрученной на максимум чувствительности, человеку надо было подойти не дальше 2 метров и постоять-подвигаться, чтобы датчик его заметил. А я хотел сделать индикатор присутствия за дверью. В общем, для определения преграды (человека, который может в коридоре получить дверью по лбу) был выбран датчик HC-SR04. Мне повезло, и я быстро нашел рецепт подключения его к микроконтроллеру Attiny 2313.
Ультразвуковой дальномер работает по принципу эхо-локации: сначала испукается импульс, затем ожидается эхо. По времени получения эха вычисляется расстояние с точностью 1 см на расстоянии до 3,5 метров. Автор предлагает использовать информацию о расстоянии для вывода на LCD-экран, но по сути, это можно применить для других целей.
Вместо функции
sprintf()
сделал собственную функцию для преобразования числа в строку, потому чтоsprintf()
жрёт больше половины флеш памяти контроллера.inline void prepareText(char * text, int distance)
Функция prepareText преобразует целое числоdistance
(расстояние) в строку и добавляет строку вtext
.itoa(distance, textDistance, 10);
Функцияitoa
преобразует целое числоdistance
в строкуtextDistance
в формате10
.strcat(text, textDistance);
Объединение строк. Функция добавляетtextDistance
строки srcptr в конец строкиtext
.Вот код программы:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#include «hcsr04.h»
#include «LCD.h»inline void prepareText(char * text, int distance) {
char textDistance[5];
itoa(distance, textDistance, 10);
strcat(text, «D=»);
strcat(text, textDistance);
strcat(text, «mm»);
}int main(void) {
_delay_ms(100);
lcdInit();
lcdClear();
lcdSetDisplay(LCD_DISPLAY_ON);
lcdSetCursor(LCD_CURSOR_OFF);int distance;
char text[17];
while (1) {
text[0] = ‘\0’;
distance = getDistance();
prepareText(text, distance);
lcdClear();
lcdGotoXY(0, 0);
lcdPuts(text);
_delay_ms(333);
}
}
Оригинал статьи доступен на сайте micro-pi, там же описано, как реализовать этот проект в программе Proteus и как прошить микроконтроллер.