Ультразвуковой дальномер в паре с семисегментным индикатором
- Войдите на сайт для отправки комментариев
Разобрал старый магнитофон. Нашёл в нём плату 691FF-2 с распаянным семисегментным индикатором на два разряда NX2-A040RWB.
Так как схемы к нему не предполагалось, то пришлось прозванивать все провода. Спасало то, что с одной стороны выходило именно восемь проводов (на семь сегментов в виде красных диодиков и десятичную точку), а с другой от жгута отделено было два провода. При подключении так и получилось - на эти два провода должен подходить "+" - это включает первый и/или второй разряды, на восемь проводов "-" - это включает каждый из сегментов в разряде и точку.
Чтоб подключить индикатор к Ардуино (+5в. на выходе) пришлось выпаять с платы все джамперы и дополнительные светодиоды (остался на плате только сам индикатор), пробросить несколько дополнительных проводков и впаять 8 резисторов по 470 ом каждый для каждого из сегментов. Подключение к Ардуине - разъёмами от компьютерной материнской платы.

Чтобы индикатор проверить в автономном режиме решил в пару ему запустить дальномер.
Ультразвуковой дальномер HC-SR04 - от 2 см. до 4 метров.
К сожалению, на Nano получились заняты почти все цифровые пины (от D2 до D13, GND, 5v).
Скетч у дальномера совсем простой. Основную сложность у меня вызвало написание скетча для дисплея и попытка заставить его корректно отрабатывать "бегущую строку" при количестве символов больше количества разрядов индикатора.
/* Дальномер HC-SR04 в паре с двухсекторным 7-сегментным индикатором
* автор Hoplik <hoplik@hoplik.ru>
*/
byte echoPin, trigPin; // Инициализация пинов дальномера HC
byte pin_[8], pin[2]; //Инициализация массива пинов сегментов и секторов
unsigned int sectorDuration, delaySector; //Задержка между отображением разрядов цифр и сдвига секторов для значений более 2
unsigned int distance, maxdist, delayDist; // Расстояние до объекта (см.), максимальная дистанция и задержка для следующего измерения расстояния(ms)
unsigned long duration; // Длина отражённой волны в микросекундах
String distString; // Преобразование данных расстояния в строковый класс
/* Структура сегментов
* Описание пинов индикатора
* a
* _____
* | |
* f | g | b
* |_____|
* | |
* e | | c
* |_____| . dot
*
* d
* 7Seg b f a e d . c g
* PIN 0 1 2 3 4 5 6 7
* BIN 7 6 5 4 3 2 1 0
*/
#define SIGN_DEF(a, b, c, d, e, f, g, dot) \
(a+(b<<1)+(c<<2)+(d<<3)+(e<<4)+(f<<5)+(g<<6)+(dot<<7))
struct SegmentTrait
{
static byte sign[10]; //Инициализация массива знаков
};
byte SegmentTrait::sign[] =
{
SIGN_DEF(0, 0, 0, 0, 0, 1, 0, 1), //0
SIGN_DEF(0, 1, 1, 1, 1, 1, 0, 1), //1
SIGN_DEF(0, 1, 0, 0, 0, 1, 1, 0), //2
SIGN_DEF(0, 1, 0, 1, 0, 1, 0, 0), //3
SIGN_DEF(0, 0, 1, 1, 1, 1, 0, 0), //4
SIGN_DEF(1, 0, 0, 1, 0, 1, 0, 0), //5
SIGN_DEF(1, 0, 0, 0, 0, 1, 0, 0), //6
SIGN_DEF(0, 1, 0, 1, 1, 1, 0, 1), //7
SIGN_DEF(0, 0, 0, 0, 0, 1, 0, 0), //8
SIGN_DEF(0, 0, 0, 1, 0, 1, 0, 0), //9
};
void setup()
{
sectorDuration = 5; // Delay for sectors
delayDist = 500; // Delay for next distance count
delaySector = 500; // Delay for sectors movie
maxdist = 400; // Maximum distance cm.
echoPin = 13; // HC Echo Pin
trigPin = 12; // HC Trig Pin
pin[0] = 10; //Pin d1 to digital pin 10
pin[1] = 11; //Pin d2 to digital pin 11
pin_[0] = 3; //Pin b to digital pin 3
pin_[1] = 7; //Pin f to digital pin 7
pin_[2] = 2; //Pin a to digital pin 2
pin_[3] = 6; //Pin e to digital pin 6
pin_[4] = 5; //Pin d to digital pin 5
pin_[5] = 9; //Pin dot to digital pin 9
pin_[6] = 4; //Pin c to digital pin 4
pin_[7] = 8; //Pin g to digital pin 8
//Определяем пины для семи сегментов и точки
for (byte i = 0; i < 8; ++i)
{
pinMode(pin_[i], OUTPUT);
}
//Определяем пины для секторов
for (byte i = 0; i < 2; ++i)
{
pinMode(pin[i], OUTPUT);
}
//Определяем пины для дальномера
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600); // Порт будем использовать для контроля данных
}
void loop() {
digitalWrite(trigPin, HIGH); // Свистнули
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); // Посчитали время отражённой волны
distance = duration/58; //Расчёт дистанции (в см.) на основе скорости звука
if (distance <= maxdist) { //Если в рамках максимальной дальности дальномера, то значение выводим на индикатор
unsigned long endTime = millis() + delayDist; //Задержка перед следующим измерением дистанции
Serial.println(distance);
while (millis () < endTime) { //Выбор подпрограммы для индикатора в зависимости от количества символов
distString = (String) distance;
switch (distString.length()) {
case 1:
printSingleSign(distance,0);
break;
case 2:
printDoubleSign(distString);
break;
case 3:
printMultiSign(distString);
break;
}
}
}
else {
clean();
Serial.print("Distance out of range - ");
Serial.println(distance);
delay (delayDist);
}
}
//Подпрограммы исполнения печати значений
void pickSector(byte i) //"Активировать указанный разряд" (номер разряда)
{
for (byte j = 0; j < 2; ++j)
{
digitalWrite(pin[j], LOW);
}
digitalWrite(pin[i], HIGH);
}
void clean() //"Очистить всё"
{
for (byte i = 0; i < 8; ++i)
{
digitalWrite(pin_[i], HIGH);
}
}
void printSign(byte n) //"Печать одного знака" (номер знака)
{
byte m = SegmentTrait::sign[n];
for (byte i = 0; i < 8; ++i)
{
digitalWrite(pin_[i], m & 0x01);
m >>= 1;
}
}
void printSingleSign (byte n, byte i) //"Печать одного символа в указанном разряде" (номер знака, номер разряда)
{
clean();
pickSector(i);
printSign(n);
}
void printDoubleSign (String n) //"Печать строки из двух символов" (Числовая строка для отображения из двух символов)
{
clean();
byte k = 1;
for (byte i = 0; i < 2; ++i) {
pickSector(i);
printSign(byte (n[k]) - 48);
k-=1;
delay (sectorDuration);
}
}
void printMultiSign (String n) //"Печать строки из нескольких символов" (Числовая строка из более чем двух символов)
{
clean();
printSingleSign(byte (n[0]) - 48, 0); // Первый знак в первом разряде
delay(delaySector);
for (byte i = 0; i < n.length() - 1; ++i) { // Все средние
unsigned long endTimeSector = millis() + delaySector; //Задержка перед следующим сдвигом разряда
while (millis () < endTimeSector) {
String newstr = String((n[i]-48)*10 + (n[i + 1]-48));
printDoubleSign (newstr);
}
}
printSingleSign(byte (n[n.length() - 1]) - 48, 1); // Последний знак во втором разряде
delay(delaySector);
}
Заинтересовал данный прибор.Однако мне кажется нужно применить 74HC595 для освобождения портов и выводить информацию по SPI на семисигментник(и).Есть затея сделать такое - нажимаешь на кнопку,ардуино высчитывает расстояние, после выводит значение в на некоторое время на индикатор(выводит среднее значение),можно до 10х долей.