Ультразвуковой дальномер в паре с семисегментным индикатором
- Войдите на сайт для отправки комментариев
Разобрал старый магнитофон. Нашёл в нём плату 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х долей.