Контакти

Направи си сам оръжеен хронограф. Евтин хронограф "направи си сам" за пневматика. Как работи самостоятелно изработен хронограф

В първата си публикация искам да ви разкажа как сглобих хронограф за няколко вечери от евтини и достъпни части. Както вероятно вече се досещате от името, това устройство се използва за измерване на скоростта на куршум във въздушни (и не толкова) пушки и е полезно за наблюдение на техническото му състояние.

1. Части и аксесоари

  • Китайски Digispark - 80 рубли в момента на покупката
  • Сегментен дисплей на TM1637 - 90 рубли в момента на покупката
  • IR светодиоди и IR фототранзистори (10 чифта) - 110 рубли към момента на покупката, имаме нужда от 2 чифта
  • Резистори 220 ома (100 бр.) - 70 рубли в момента на покупката, имаме нужда само от 2 броя
Това приключва частите, които трябва да бъдат закупени. Резисторите могат да бъдат пропуснати, подобни по стойност (но не по-малко!) Могат да бъдат извадени от ненужната потребителска електроника. Така общите разходи са по-малко от 350 рубли, което е нищо в сравнение с цената на нов фабричен хронограф (над 1000 рубли за най-простия, който всъщност е дори по-примитивен от нашата тема). В допълнение към подробностите ще ни трябва:
  • Проводници - намирането офлайн безплатно не е проблем
  • парче пластмаса водопроводна тръбас дължина над 10 см (диаметър на вкус) - също толкова лесен за намиране
  • Аксесоари за запояване
  • Мултиметър (по избор)
Първите 3 подробности заслужават отделно разглеждане, тъй като имат свои собствени характеристики, така че нека започнем с мини-ревюта за тях.

1.1. Digispark

Това е проста миниатюрна Arduino-съвместима платка с ATtiny85 на борда. Прочетохме как да се свържете с Arduino IDE на официалния уебсайт на проекта, където можете да намерите и драйвери за него. Има два основни типа на тази платка: с microUSB и по-брутален с USB конектор, свързан директно на платката.

Моят хронограф няма собствено захранване, затова избрах първия вариант на платката. Вградената батерия/акумулатор значително ще увеличи цената, като същевременно не добави почти нищо към използваемостта. Почти всеки има power bank и кабел за зареждане на телефона.

Спецификацииразбира се наследено от ATtiny85, неговите възможности в нашия случай са достатъчни с главата. Всъщност MK в хронографа не прави нищо друго, освен да разпитва двата сензора и да управлява дисплея. За тези, които се сблъскват с Digispark за първи път, обобщих най-важните характеристики в таблица:

Използвам тази плоча като cheat sheet, когато разработвам различни устройства, базирани на тази платка. Както вероятно сте забелязали, номерирането на щифтовете за функцията analogRead() е различно, това трябва да се вземе предвид. И още една особеност: издърпващ резистор от 1,5 kOhm виси на третия щифт, т.к. използва се в USB.

1.2. Дисплей, базиран на TM1637

Следващият важен детайл е цифров дисплей, на който ще се извежда информация. Всеки дисплей може да се използва, моят избор се дължи само на евтиността и лекотата на работа с него. По принцип можете напълно да откажете дисплея и да изведете данни чрез кабел към компютър, тогава устройството ще стане още по-евтино. За да работите, ви е необходима библиотеката DigitalTube. Темата, към която дадох връзка в началото на публикацията, е клонинг на дисплея на Grove. Изглед отпред:

Разстоянието между цифрите е същото, така че когато двоеточието е изключено, числовите стойности се четат нормално. Заедно със стандартната библиотека се доставя пример, който работи с Digispark без да танцува с тамбура:

Всичко, което стандартната библиотека може да направи, е да отпечата числата 0-9 и букви a-f, както и промяна на яркостта на целия дисплей. Стойността на цифра се дава от функцията на дисплея (int 0-3, int 0-15).

Експресен курс за използване на дисплея

// 1. Декларирайте заглавния файл #include // 2. Дефиниране на щифтове #define CLK 0 #define DIO 1 // 3. Деклариране на TM1637 обект tm1637(CLK, DIO); // 4. Инициализирайте void setup() ( tm1637.init(); tm1637.set(6); // Яркост ) // 5. Използвайте void loop() ( // Показване на числото x на дисплея int x = 1234 ; tm1637 .display(0, x / 1000); tm1637.display(1, x / 100% 10); tm1637.display(2, x / 10% 10); tm1637.display(3, x % 10); забавяне (500) );)


Ако се опитате да покажете символ с код извън границите, тогава дисплеят показва глупости, които не са статични, така че няма да можете да мамите за показване на специални символи (градуси, минус) без тамбура:

Това не ме устройваше, тъй като в моя хронограф исках да осигуря изхода не само на скоростта, но и на енергията на куршума (изчислена въз основа на масата, предварително написана в скицата), тези две стойности ​Трябва да се показва последователно. За да разберете какво показва дисплеят в даден момент от време, трябва по някакъв начин да разделите тези две стойности ​​​​визуално, например, като използвате символа „J“. Разбира се, можете глупаво да използвате символа на двоеточие като индикатор за флаг, но това не е вярно и не е кошер) Затова влязох в библиотеката и въз основа на функцията за показване направих функцията setSegments(byte addr, byte data) , който светва на фигурата със сегментите на числото addr, кодирани в данни:

Невалидни setSegments(byte addr, byte data) (tm1637.start(); tm1637.writeByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte(addr|0xc63); tmriteByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte(addr|0xc63). ; tm1637.stop(); tm1637.start(); tm1637.writeByte(tm1637.Cmd_DispCtrl); tm1637.stop(); )
Сегментите се кодират изключително просто: най-малкият бит от данни е отговорен за най-горния сегмент и т.н. по посока на часовниковата стрелка, седмият бит е отговорен за централния сегмент. Например, символът "1" е кодиран като 0b00000110. Осмият, най-значим бит се използва само във втората цифра и е отговорен за двоеточие, при всички останали цифри се игнорира. За да улесня живота си, както би трябвало всеки мързелив ИТ специалист, автоматизирах процеса на получаване на кодове на знаци с помощта на excel:

Сега можете лесно да направите това:

Да кажем ЗДРАВЕЙ

#включи #define CLK 0 #define DIO 1 TM1637 tm1637(CLK, DIO); void setSegments(byte addr, byte data) ( tm1637.start(); tm1637.writeByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte(addr|0xc63); tmriteByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte(addr|0xc63). ; tm1637.stop(); tm1637.start(); tm1637.writeByte(tm1637.Cmd_DispCtrl); tm1637.stop(); ) void setup() ( tm1637.init(); tm1637.setoid(6lo); () ( // Извеждане Здравейте setSegments(0, 118); setSegments(1, 121); setSegments(2, 54); setSegments(3, 63); забавяне (500); )

1.3. Сензори

Тук, за съжаление, не мога да кажа нищо особено, защото на продуктовата страница няма нито дума за характеристиките или поне маркировки, по които може да се изрови листа с данни. Типичен noname. Известна е само дължината на вълната от 940 nm.

На цената на един светодиод определих, че ток над 40mA е фатален за тях, а захранващото напрежение трябва да е под 3.3V. Фототранзисторът е леко прозрачен и реагира на светлина

2. Подготовка на части и монтаж

Схемата е много проста и неусложнена, от всички щифтове digispark-a ни трябват само P0, P1 - за работа с дисплея, както и P2 - за работа със сензори:

Както можете да видите, един резистор ограничава тока на светодиодите, вторият дърпа P2 към земята. Фототранзисторите са свързани последователно, така че преминаването на куршум пред всеки оптрон води до намаляване на напрежението в P2. Чрез регистриране на две последователни скокове на захранване и измерване на времето между тях можем да определим скоростта на куршума (очевидно, като знаем разстоянието между сензорите). Използването на един мерителен щифт има още един плюс - няма необходимата посока на куршума, можете да стреляте от двата края. Ще съберем от тази шепа части:

Тръгнах по пътя на миниатюризацията и реших да направя сандвич с помощта на парче дъска:

Целият сандвич беше пълен с горещо лепило за здравина:

Остава само да поставите сензорите в тръбата и да спойкате проводниците:

Снимката показва, че поставих допълнителен електролит на 100mKf успоредно на светодиодите, така че при захранване от power bank да няма пулсации на IR диодите.

Пин P2 беше избран като вход по причина. Нека ви напомня, че P3 и P4 се използват в USB, така че използването на P2 прави възможно флашването на вече сглобеното устройство. Второ, P2 е аналогов вход, така че не можете да използвате прекъсвания, а просто измервате разликата в цикъла между предишната и текущата стойност върху него, ако разликата е над определен праг, тогава куршумът преминава между един от оптроните . Но има един софтуерен трик, без който горната схема няма да излети, ще говорим за това по-късно.

3. Фърмуер

3.1. Няколко думи за prescaler

Prescaler е честотен делител, по подразбиране в платки, подобни на arduino е 128. Максималната честота на запитване на ADC зависи от стойността на тази стойност, по подразбиране за 16 MHz контролер се оказва 16/128 = 125 kHz. Всяко цифровизиране отнема 13 операции, така че максималната честота на запитване на щифтове е 9600 kHz (на теория, на практика тя наистина не надвишава 7 kHz). Тези. интервалът между измерванията е приблизително 120 μs, което е много, много. Куршум, летящ със скорост 300 m / s, ще лети 3,6 см през това време - контролерът просто няма време да открие факта, че куршумът преминава през оптрона. За нормална работа ви е необходим интервал между измерванията от най-малко 20 µs, необходимата стойност на делителя за това е 16. Отидох още по-далеч и използвах делител на 8 в моето устройство, това се прави по следния начин:

#ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) # endif void setup() ( sbi(ADCSRA,ADPS2); cbi(ADCSRA,ADPS1); cbi(ADCSRA,ADPS0); ... )
Реални измервания на аналоговия интервал на четене на различни делители:

3.2. Финална скица

Няма да описвам подробно кода, той вече е добре документиран. Вместо това съм вътре в общи линииЩе опиша алгоритъма на неговата работа. И така, цялата логика се свежда до следните стъпки:
  • Първият цикъл - измерва се разликата между текущата и предишната стойност на щифта
  • Ако разликата е по-голяма от посочения праг, излезте от цикъла и запомнете текущото време (микро())
  • Втори цикъл - подобен на предишния + брояч на времето в цикъла
  • Ако броячът е достигнал посочената стойност, информирайте за грешката и отидете в началото. Това позволява на цикъла да не отива във вечността, ако куршумът по някаква причина не е забелязан от втория сензор.
  • Ако броячът не е прелял и разликата в стойностите е по-голяма от прага, тогава измерваме текущото време (микро())
  • Въз основа на разликата във времето и разстоянието между сензорите изчисляваме скоростта и я показваме на екрана
  • Отидете да започнете
Това е значително опростен модел, в самия код добавих свирка, включваща изчисляването и показването на енергията на куршума въз основа на масата на куршума, въведена предварително в кода.

Всъщност целият код

/* * Хронограф на скоростта на куршуми, SinuX 23.03.2016 г. */ #include #define CLK 1 // Показване на щифт #define DIO 0 // Показване на щифт #define START_PIN 1 // Аналогов стартов щифт #define END_PIN 1 // Аналогов завършващ щифт #define START_LEV 50 // Стартов праг #define END_LEV 50 // Край на прага triggering #define TIMEOUT 10000 // Време за изчакване за край в микросекунди #define BULLET_WEIGHT 0.00051 // Тегло на куршума в килограми (за изчисляване на енергия) #define ENCODER_DIST 0.1 // Разстояние между сензорите в метри (10cm = 0.1m) #define AY 0 /define / Време на показване // За да ускорите analogRead #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) ) |= _BV(bit)) #endif // Променливи на услугата int prevVal, curVal; unsigned long startTime, endTime; TM1637 tm1637 (CLK, DIO); /* Преработена функция TM1637::display(), която ви позволява да осветявате отделни сегменти * Номериране на сегменти: нисък бит - висок сегмент и т.н. по посока на часовниковата стрелка * Централният сегмент е най-значимият бит */ void setSegments(byte addr, byte data) ( tm1637.start(); tm1637.writeByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte( addrByte |0xc0); tm1637.writeByte(data); tm1637.stop(); tm1637.start(); tm1637.writeByte(tm1637.Cmd_DispCtrl); tm1637.stop(); ) // Инициализация () невалидна настройка прескалер до 8 за ускоряване на analogRead cbi(ADCSRA,ADPS2); sbi(ADCSRA,ADPS1); sbi(ADCSRA,ADPS0); // Инициализация на дисплея tm1637.init(); tm1637.set(6); // Показване на поздравителни набориSegments (0, 118); setSegments(1, 121); setSegments(2, 54); setSegments(3, 63); delay(1000); ) // Главен цикъл void loop() ( // Чакащ начален екран showReady() ; // Изчакайте старта curVal = analogRead(START_PIN); do ( prevVal = curVal; curVal = analogRead(START_PIN); ) while (curVal - prevVal< START_LEV); startTime = micros(); // Ожидание финиша curVal = analogRead(END_PIN); do { prevVal = curVal; curVal = analogRead(END_PIN); // Если превышен интервал ожидания - показ ошибки и выход из цикла if (micros() - startTime >= TIMEOUT) ( showError(); return; ) ) while (curVal - prevVal< END_LEV); endTime = micros(); // Вычисление и отображение результата showResult(); } // Отображение заставки ожидания выстрела void showReady() { setSegments(0, 73); setSegments(1, 73); setSegments(2, 73); setSegments(3, 73); delay(100); } // Вычисление и отображение скорости, энергии пули void showResult() { // Вычисление скорости пули в м/с и вывод на дисплей float bulletSpeed = ENCODER_DIST * 1000000 / (endTime - startTime); tm1637.display(0, (int)bulletSpeed / 100 % 10); tm1637.display(1, (int)bulletSpeed / 10 % 10); tm1637.display(2, (int)bulletSpeed % 10); setSegments(3, 84); delay(SHOW_DELAY); // Вычисление энергии в джоулях и вывод на дисплей float bulletEnergy = BULLET_WEIGHT * bulletSpeed * bulletSpeed / 2; tm1637.point(1); // Вместо точки ":" - костыль, но пойдет) tm1637.display(0, (int)bulletEnergy / 10 % 10); tm1637.display(1, (int)bulletEnergy % 10); tm1637.display(2, (int)(bulletEnergy * 10) % 10); setSegments(3, 30); delay(SHOW_DELAY); tm1637.point(0); } // Вывод ошибки при превышении времени ожидания пули void showError() { setSegments(0, 121); setSegments(1, 80); setSegments(2, 80); setSegments(3, 0); delay(SHOW_DELAY); }

4. Примери за работа

Когато е правилно свързан, устройството излетя почти веднага, единственият открит недостатък е, че реагира отрицателно на LED и флуоресцентно осветление (честотата на импулса е около 40 kHz), поради което могат да се появят спонтанни грешки. Като цяло устройството има 3 режима на работа:

Поздрав след включване и превключване в режим на готовност за кадър (екранът е пълен с ивици):

В случай на грешка се показва "Err" и отново преминава в режим на готовност:

Е, самото измерване на скоростта:

След изстрела първо се показва скоростта на куршума (със символ "n"), след това - енергията (символ "J"), а енергията се изчислява с точност до един знак след десетичната запетая (на gif-а можете да видите, че когато са показани джаулите, дебелото черво е включено). Все още не успях да намеря по-красив калъф, така че просто напълних всичко с термични сополи:

Може би това е всичко, което имам, надявам се да е било полезно на някой.

В първата си публикация искам да ви разкажа как сглобих хронограф за няколко вечери от евтини и достъпни части. Както вероятно вече се досещате от името, това устройство се използва за измерване на скоростта на куршум във въздушни (и не толкова) пушки и е полезно за наблюдение на техническото му състояние.

1. Части и аксесоари

  • Китайски Digispark - 80 рубли в момента на покупката
  • Сегментен дисплей на TM1637 - 90 рубли в момента на покупката
  • IR светодиоди и IR фототранзистори (10 чифта) - 110 рубли към момента на покупката, имаме нужда от 2 чифта
  • Резистори 220 ома (100 бр.) - 70 рубли в момента на покупката, имаме нужда само от 2 броя
Това приключва частите, които трябва да бъдат закупени. Резисторите могат да бъдат пропуснати, подобни по стойност (но не по-малко!) Могат да бъдат извадени от ненужната потребителска електроника. Така общите разходи са по-малко от 350 рубли, което е нищо в сравнение с цената на нов фабричен хронограф (над 1000 рубли за най-простия, който всъщност е дори по-примитивен от нашата тема). В допълнение към подробностите ще ни трябва:
  • Проводници - намирането офлайн безплатно не е проблем
  • Парче пластмасова водопроводна тръба с дължина над 10 см (диаметър на вкус) - също толкова лесно за намиране
  • Аксесоари за запояване
  • Мултиметър (по избор)
Първите 3 подробности заслужават отделно разглеждане, тъй като имат свои собствени характеристики, така че нека започнем с мини-ревюта за тях.

1.1. Digispark

Това е проста миниатюрна Arduino-съвместима платка с ATtiny85 на борда. Прочетохме как да се свържете с Arduino IDE на официалния уебсайт на проекта, където можете да намерите и драйвери за него. Има два основни типа на тази платка: с microUSB и по-брутален с USB конектор, свързан директно на платката.

Моят хронограф няма собствено захранване, затова избрах първия вариант на платката. Вградената батерия/акумулатор значително ще увеличи цената, като същевременно не добави почти нищо към използваемостта. Почти всеки има power bank и кабел за зареждане на телефона.

Спецификацииразбира се наследено от ATtiny85, неговите възможности в нашия случай са достатъчни с главата. Всъщност MK в хронографа не прави нищо друго, освен да разпитва двата сензора и да управлява дисплея. За тези, които се сблъскват с Digispark за първи път, обобщих най-важните характеристики в таблица:

Използвам тази плоча като cheat sheet, когато разработвам различни устройства, базирани на тази платка. Както вероятно сте забелязали, номерирането на щифтовете за функцията analogRead() е различно, това трябва да се вземе предвид. И още една особеност: издърпващ резистор от 1,5 kOhm виси на третия щифт, т.к. използва се в USB.

1.2. Дисплей, базиран на TM1637

Следващият важен детайл е цифров дисплей, на който ще се извежда информация. Всеки дисплей може да се използва, моят избор се дължи само на евтиността и лекотата на работа с него. По принцип можете напълно да откажете дисплея и да изведете данни чрез кабел към компютър, тогава устройството ще стане още по-евтино. За да работите, ви е необходима библиотеката DigitalTube. Темата, към която дадох връзка в началото на публикацията, е клонинг на дисплея на Grove. Изглед отпред:

Разстоянието между цифрите е същото, така че когато двоеточието е изключено, числовите стойности се четат нормално. Заедно със стандартната библиотека се доставя пример, който работи с Digispark без да танцува с тамбура:

Всичко, което стандартната библиотека може да направи, е да отпечата числата 0-9 и буквите a-f, както и да промени яркостта на целия дисплей. Стойността на цифра се дава от функцията на дисплея (int 0-3, int 0-15).

Експресен курс за използване на дисплея

// 1. Декларирайте заглавния файл #include // 2. Дефиниране на щифтове #define CLK 0 #define DIO 1 // 3. Деклариране на TM1637 обект tm1637(CLK, DIO); // 4. Инициализирайте void setup() ( tm1637.init(); tm1637.set(6); // Яркост ) // 5. Използвайте void loop() ( // Показване на числото x на дисплея int x = 1234 ; tm1637 .display(0, x / 1000); tm1637.display(1, x / 100% 10); tm1637.display(2, x / 10% 10); tm1637.display(3, x % 10); забавяне (500) );)


Ако се опитате да покажете символ с код извън границите, тогава дисплеят показва глупости, които не са статични, така че няма да можете да мамите за показване на специални символи (градуси, минус) без тамбура:

Това не ме устройваше, тъй като в моя хронограф исках да осигуря изхода не само на скоростта, но и на енергията на куршума (изчислена въз основа на масата, предварително написана в скицата), тези две стойности ​Трябва да се показва последователно. За да разберете какво показва дисплеят в даден момент от време, трябва по някакъв начин да разделите тези две стойности ​​​​визуално, например, като използвате символа „J“. Разбира се, можете глупаво да използвате символа на двоеточие като индикатор за флаг, но това не е вярно и не е кошер) Затова влязох в библиотеката и въз основа на функцията за показване направих функцията setSegments(byte addr, byte data) , който светва на фигурата със сегментите на числото addr, кодирани в данни:

Невалидни setSegments(byte addr, byte data) (tm1637.start(); tm1637.writeByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte(addr|0xc63); tmriteByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte(addr|0xc63). ; tm1637.stop(); tm1637.start(); tm1637.writeByte(tm1637.Cmd_DispCtrl); tm1637.stop(); )
Сегментите се кодират изключително просто: най-малкият бит от данни е отговорен за най-горния сегмент и т.н. по посока на часовниковата стрелка, седмият бит е отговорен за централния сегмент. Например, символът "1" е кодиран като 0b00000110. Осмият, най-значим бит се използва само във втората цифра и е отговорен за двоеточие, при всички останали цифри се игнорира. За да улесня живота си, както би трябвало всеки мързелив ИТ специалист, автоматизирах процеса на получаване на кодове на знаци с помощта на excel:

Сега можете лесно да направите това:

Да кажем ЗДРАВЕЙ

#включи #define CLK 0 #define DIO 1 TM1637 tm1637(CLK, DIO); void setSegments(byte addr, byte data) ( tm1637.start(); tm1637.writeByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte(addr|0xc63); tmriteByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte(addr|0xc63). ; tm1637.stop(); tm1637.start(); tm1637.writeByte(tm1637.Cmd_DispCtrl); tm1637.stop(); ) void setup() ( tm1637.init(); tm1637.setoid(6lo); () ( // Извеждане Здравейте setSegments(0, 118); setSegments(1, 121); setSegments(2, 54); setSegments(3, 63); забавяне (500); )

1.3. Сензори

Тук, за съжаление, не мога да кажа нищо особено, защото на продуктовата страница няма нито дума за характеристиките или поне маркировки, по които може да се изрови листа с данни. Типичен noname. Известна е само дължината на вълната от 940 nm.

На цената на един светодиод определих, че ток над 40mA е фатален за тях, а захранващото напрежение трябва да е под 3.3V. Фототранзисторът е леко прозрачен и реагира на светлина

2. Подготовка на части и монтаж

Схемата е много проста и неусложнена, от всички щифтове digispark-a ни трябват само P0, P1 - за работа с дисплея, както и P2 - за работа със сензори:

Както можете да видите, един резистор ограничава тока на светодиодите, вторият дърпа P2 към земята. Фототранзисторите са свързани последователно, така че преминаването на куршум пред всеки оптрон води до намаляване на напрежението в P2. Чрез регистриране на две последователни скокове на захранване и измерване на времето между тях можем да определим скоростта на куршума (очевидно, като знаем разстоянието между сензорите). Използването на един мерителен щифт има още един плюс - няма необходимата посока на куршума, можете да стреляте от двата края. Ще съберем от тази шепа части:

Тръгнах по пътя на миниатюризацията и реших да направя сандвич с помощта на парче дъска:

Целият сандвич беше пълен с горещо лепило за здравина:

Остава само да поставите сензорите в тръбата и да спойкате проводниците:

Снимката показва, че поставих допълнителен електролит на 100mKf успоредно на светодиодите, така че при захранване от power bank да няма пулсации на IR диодите.

Пин P2 беше избран като вход по причина. Нека ви напомня, че P3 и P4 се използват в USB, така че използването на P2 прави възможно флашването на вече сглобеното устройство. Второ, P2 е аналогов вход, така че не можете да използвате прекъсвания, а просто измервате разликата в цикъла между предишната и текущата стойност върху него, ако разликата е над определен праг, тогава куршумът преминава между един от оптроните . Но има един софтуерен трик, без който горната схема няма да излети, ще говорим за това по-късно.

3. Фърмуер

3.1. Няколко думи за prescaler

Prescaler е честотен делител, по подразбиране в платки, подобни на arduino е 128. Максималната честота на запитване на ADC зависи от стойността на тази стойност, по подразбиране за 16 MHz контролер се оказва 16/128 = 125 kHz. Всяко цифровизиране отнема 13 операции, така че максималната честота на запитване на щифтове е 9600 kHz (на теория, на практика тя наистина не надвишава 7 kHz). Тези. интервалът между измерванията е приблизително 120 μs, което е много, много. Куршум, летящ със скорост 300 m / s, ще лети 3,6 см през това време - контролерът просто няма време да открие факта, че куршумът преминава през оптрона. За нормална работа ви е необходим интервал между измерванията от най-малко 20 µs, необходимата стойност на делителя за това е 16. Отидох още по-далеч и използвах делител на 8 в моето устройство, това се прави по следния начин:

#ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) # endif void setup() ( sbi(ADCSRA,ADPS2); cbi(ADCSRA,ADPS1); cbi(ADCSRA,ADPS0); ... )
Реални измервания на аналоговия интервал на четене на различни делители:

3.2. Финална скица

Няма да описвам подробно кода, той вече е добре документиран. Вместо това ще опиша в общи линии алгоритъма на неговата работа. И така, цялата логика се свежда до следните стъпки:
  • Първият цикъл - измерва се разликата между текущата и предишната стойност на щифта
  • Ако разликата е по-голяма от посочения праг, излезте от цикъла и запомнете текущото време (микро())
  • Втори цикъл - подобен на предишния + брояч на времето в цикъла
  • Ако броячът е достигнал посочената стойност, информирайте за грешката и отидете в началото. Това позволява на цикъла да не отива във вечността, ако куршумът по някаква причина не е забелязан от втория сензор.
  • Ако броячът не е прелял и разликата в стойностите е по-голяма от прага, тогава измерваме текущото време (микро())
  • Въз основа на разликата във времето и разстоянието между сензорите изчисляваме скоростта и я показваме на екрана
  • Отидете да започнете
Това е значително опростен модел, в самия код добавих свирка, включваща изчисляването и показването на енергията на куршума въз основа на масата на куршума, въведена предварително в кода.

Всъщност целият код

/* * Хронограф на скоростта на куршуми, SinuX 23.03.2016 г. */ #include #define CLK 1 // Показване на щифт #define DIO 0 // Показване на щифт #define START_PIN 1 // Аналогов стартов щифт #define END_PIN 1 // Аналогов завършващ щифт #define START_LEV 50 // Стартов праг #define END_LEV 50 // Край на прага triggering #define TIMEOUT 10000 // Време за изчакване за край в микросекунди #define BULLET_WEIGHT 0.00051 // Тегло на куршума в килограми (за изчисляване на енергия) #define ENCODER_DIST 0.1 // Разстояние между сензорите в метри (10cm = 0.1m) #define AY 0 /define / Време на показване // За да ускорите analogRead #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) ) |= _BV(bit)) #endif // Променливи на услугата int prevVal, curVal; unsigned long startTime, endTime; TM1637 tm1637 (CLK, DIO); /* Преработена функция TM1637::display(), която ви позволява да осветявате отделни сегменти * Номериране на сегменти: нисък бит - висок сегмент и т.н. по посока на часовниковата стрелка * Централният сегмент е най-значимият бит */ void setSegments(byte addr, byte data) ( tm1637.start(); tm1637.writeByte(ADDR_FIXED); tm1637.stop(); tm1637.start(); tm1637.writeByte( addrByte |0xc0); tm1637.writeByte(data); tm1637.stop(); tm1637.start(); tm1637.writeByte(tm1637.Cmd_DispCtrl); tm1637.stop(); ) // Инициализация () невалидна настройка прескалер до 8 за ускоряване на analogRead cbi(ADCSRA,ADPS2); sbi(ADCSRA,ADPS1); sbi(ADCSRA,ADPS0); // Инициализация на дисплея tm1637.init(); tm1637.set(6); // Показване на поздравителни набориSegments (0, 118); setSegments(1, 121); setSegments(2, 54); setSegments(3, 63); delay(1000); ) // Главен цикъл void loop() ( // Чакащ начален екран showReady() ; // Изчакайте старта curVal = analogRead(START_PIN); do ( prevVal = curVal; curVal = analogRead(START_PIN); ) while (curVal - prevVal< START_LEV); startTime = micros(); // Ожидание финиша curVal = analogRead(END_PIN); do { prevVal = curVal; curVal = analogRead(END_PIN); // Если превышен интервал ожидания - показ ошибки и выход из цикла if (micros() - startTime >= TIMEOUT) ( showError(); return; ) ) while (curVal - prevVal< END_LEV); endTime = micros(); // Вычисление и отображение результата showResult(); } // Отображение заставки ожидания выстрела void showReady() { setSegments(0, 73); setSegments(1, 73); setSegments(2, 73); setSegments(3, 73); delay(100); } // Вычисление и отображение скорости, энергии пули void showResult() { // Вычисление скорости пули в м/с и вывод на дисплей float bulletSpeed = ENCODER_DIST * 1000000 / (endTime - startTime); tm1637.display(0, (int)bulletSpeed / 100 % 10); tm1637.display(1, (int)bulletSpeed / 10 % 10); tm1637.display(2, (int)bulletSpeed % 10); setSegments(3, 84); delay(SHOW_DELAY); // Вычисление энергии в джоулях и вывод на дисплей float bulletEnergy = BULLET_WEIGHT * bulletSpeed * bulletSpeed / 2; tm1637.point(1); // Вместо точки ":" - костыль, но пойдет) tm1637.display(0, (int)bulletEnergy / 10 % 10); tm1637.display(1, (int)bulletEnergy % 10); tm1637.display(2, (int)(bulletEnergy * 10) % 10); setSegments(3, 30); delay(SHOW_DELAY); tm1637.point(0); } // Вывод ошибки при превышении времени ожидания пули void showError() { setSegments(0, 121); setSegments(1, 80); setSegments(2, 80); setSegments(3, 0); delay(SHOW_DELAY); }

4. Примери за работа

Когато е правилно свързан, устройството излетя почти веднага, единственият открит недостатък е, че реагира отрицателно на LED и флуоресцентно осветление (честотата на импулса е около 40 kHz), поради което могат да се появят спонтанни грешки. Като цяло устройството има 3 режима на работа:

Поздрав след включване и превключване в режим на готовност за кадър (екранът е пълен с ивици):

В случай на грешка се показва "Err" и отново преминава в режим на готовност:

Е, самото измерване на скоростта:

След изстрела първо се показва скоростта на куршума (със символ "n"), след това - енергията (символ "J"), а енергията се изчислява с точност до един знак след десетичната запетая (на gif-а можете да видите, че когато са показани джаулите, дебелото черво е включено). Все още не успях да намеря по-красив калъф, така че просто напълних всичко с термични сополи:

Може би това е всичко, което имам, надявам се да е било полезно на някой.

Хронографът е универсален инструмент, способен да измерва скоростта на малки обекти. Най-удобно е да настроите и тествате пневматиката с хронографи тип рамка. Те могат да открият движението на куршуми, арбалетни болтове, стрели, скоби за прашка. Можете да направите хронограф за пневматика със собствените си ръце или да го закупите в специализирани магазини.

Видове хронографи

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

Има различни видове хронографи. Надуваемият модел заема малко място и се побира лесно в джоба на калъфа, а освен това изразходва по-малко енергия. За определен вид оръжие може да ви трябва адаптер. Този тип не зависи от осветлението и е удобен за използване в природата. Заедно с устройството може да се извършва насочена стрелба. За CO2 този модел не е подходящ.

Ако имате впечатляващ арсенал, по-добре е да закупите рамков хронограф да не купувам голям бройадаптери. Този тип устройство работи добре с CO2, има конектор за външно захранване. Бронята ви позволява да измервате индикатори на различни разстояния, без да се страхувате от повреда на механизма. Наличието на допълнителен екран помага за бързо получаване на резултати.

Има и модели с големи рамки, които разширяват броя на възможностите. Тази опция е подходяща за използване с всякакъв вид оръжие, удобна е за стационарна връзка към мрежата. Като алтернатива, хронографът може да се захранва от осем батерии АА. За разлика от малкия модел, голямата машина има вграден преден индикатор. По желание можете да инсталирате подвижен екран. С помощта на USB адаптера можете да прехвърляте измервателни данни от устройството към компютър.

Купуване на хронограф за пневматика

Можете да закупите различни видове хронографи в Москва и Санкт Петербург в следните магазини:

  • Магазин Airgun - на цена от 3500 до 24 хиляди рубли;
  • Diada Arms - на цена от 4 хиляди до 13 хиляди рубли;
  • Pnevmat 24 - на цена от 4 хиляди до 7 хиляди рубли;
  • Oxotnika.net - на цена от 3 хиляди до 20 хиляди рубли.

Тези магазини предлагат и разнообразие от части и аксесоари за хронографи. Можете да закупите по-бюджетен модел на AliExpress на цена от 3 хиляди рубли. или купете употребяван, например на портала Guns.ru или Avito на цена от 1500 рубли.

Направи сам хронограф тип рамка за пневматика

Хронографът записва времето за полет на куршума между множество сензори и изчислява неговата скорост. Устройството се състои от три части:

  • работна зона, прокарваща куршум през себе си;
  • схема, която извършва изчисления;
  • дисплей, показващ изчислените резултати.

Схемите за хронограф могат да бъдат различни по цена, функционалност и дизайн. Най-простите сензори отчитат падащата върху тях светлина, чийто интензитет се променя с движението на куршума, хвърлящ сянка. Светлочувствителните елементи са част от много домашни и фабрично изработени хронографи.

Самоделното устройство има няколко предимства:

Заедно с това, устройството има свой собствен ограничения:

  • тромав дизайн;
  • необходимостта от защита от проникване на лицето на работната зона;
  • влияние на атмосферните условия и осветлението върху работата;
  • чувствителност на оптическата схема към значителни механични въздействия, включително фрагменти от куршуми и рикошети;
  • извеждане на фалшиви показания при поява в камерата чужди предмети, като сняг, насекоми или механични фрагменти;
  • влиянието на траекторията на полета върху записаната скорост на куршума (преместването на обекта по диагонал намалява индикатора).

Компоненти и материали за монтаж

Общият брой на частите и тяхната сложност зависят от нивото на умения на потребителя при проектирането и инсталирането на вериги. Някои компоненти са задължителноза всякакъв вид монтаж:

  • Светодиоди за създаване на изкуствен източник на светлина;
  • поялник с флюс и спойка за фиксиране на проводници и инсталиране на микросхема;
  • оптични приемници за отчитане на нивото на осветеност по време на преминаване на куршум през светодиодите;
  • микросхема за определяне на времето на полет на куршум и изчисляване на скоростта;
  • дисплей за показване на резултатите от измерването;
  • правоъгълно кухо тяло, затворено от четири страни (по-добре е да изберете твърд метален продукт, който ще бъде устойчив на удар).

Стъпки за монтаж на хронограф

Елементите на микросхемата и сензорите трябва да бъдат защитени или разположени на места, които няма да бъдат достъпни за директен удар от куршум. Под тях трябва предварително да подготвите място в кутията. Вътрешността на продукта е покрита с тъмна боя, която не създава отблясъци, за да се избегне ненужна работа с устройството и да се увеличи чувствителността му.

Светлочувствителните елементи и самите светодиоди са монтирани в предварително маркирани отвори. Фотодетекторите трябва да са леко вдлъбнати, а светодиодите трябва да са леко издути във вътрешността на хронографа. Тази подредба ще намали интензитета на външната светлина, падаща върху устройството.

На следващия етап платката е инсталирана и свързана към сензорите, секциите са маркирани за захранване. За самостоятелно изготвяне на диаграма можете да използвате фиг. един.

Ориз. 1 чип на хронограф

Когато основните компоненти са сглобени, веригата ще трябва да бъде защитена от механично натоварване и влага. За тази задача е подходяща пластмасова кутия за печатна платка, която ще има изходи към батерията, дисплея и сензорите.

Как работи самостоятелно изработен хронограф

Като източник на захранване на устройството могат да се използват батерии, акумулатори, захранване, свързано към мрежата. Автономен източник е по-изгоден и удобен, тъй като в повечето случаи настройката на оръжието се извършва извън дома.

Процесът на измерване на скоростта преминава през три етапа:

  • куршумът преминава през оста на първоначалния сензор, нулира брояча на времето в микропроцесора;
  • след като куршумът пресече оста на следващия сензор, времето спира и данните се предават за изчисления;
  • микропроцесорът извършва изчисления и показва индикаторите за скорост на дисплея.

Работата на хронографа с рамка може да се види визуално на фиг. 2.

Ориз. 2 Работна схема на хронографа

За да сглобите сами хронограф, ще ви трябват знания и опит в електротехниката, запояване и проектиране на електрически вериги. Можете да улесните задачата, като поръчате производството на микросхема на майстор по електроника. Самостоятелно сглобеният хронограф ще струва много по-малко от закупената версия.


В тази статия ще разгледаме как можете да направите обикновен хронограф от евтини и достъпни части. приспособлениенеобходими за измерване на скоростта на куршум от пушка. Тези цифри са необходими, за да се определи състоянието на пушката, тъй като с времето някои пневматични компоненти се износват и трябва да бъдат сменени.

Приготвяне необходими материалии инструменти:
- китайски Digispark (той струва 80 рубли към момента на покупката);
- дисплей тип сегмент на TM1637 (той струва 90 рубли при покупка);
- инфрачервени светодиоди и фототранзистори (10 чифта) - цената беше 110 рубли;
- сто резистора 220 ома струват 70 рубли, но ще са необходими само два от тях.

Това е всичко, това е целият списък с артикули, които ще трябва да закупите. Между другото, резистори могат да се намерят и в стария домакински уреди. Можете да залагате повече на номинална стойност, но не по-малко. В резултат на това можете да срещнете 350 рубли, но това не е толкова много, като се има предвид, че фабричният хронограф ще струва най-малко 1000 рубли, а монтажът там е много по-лош от нашия домашно приготвени.

Наред с други неща, трябва да се запасите с такива подробности като:
- проводници;
- парче тръба с дължина най-малко 10 см (подходяща е пластмасова водопроводна инсталация);
- всичко за запояване;
- мултиметър (по избор).


Първите три описани детайли имат свои собствени нюанси, така че всеки от тях трябва да се разглежда отделно.

Digispark
Този артикул е миниатюрна дъска, която е съвместима с Arduino, тя има ATtiny85 на борда. Как да свържете този елемент към Arduino IDE, можете да прочетете нататък, можете също да изтеглите драйвери за него там.
Тази платка има няколко опции, едната използва microUSB, а другата е снабдена с USB конектор, който е свързан точно на дъската. Поради факта, че домашният продукт няма индивидуално захранване, авторът избра първата версия на платката. Ако инсталирате батерия или акумулатор в домашен продукт, това значително ще увеличи цената му и няма да повлияе значително на практичността. И почти всеки има кабел за зареждане на мобилен телефон и Power bank.


Що се отнася до характеристиките, те са подобни на ATtiny85, тук неговите възможности са повече от достатъчни. Микроконтролерът в хронографа само проучва сензорите и управлява дисплея.
Ако никога не сте срещали Digispark, най-много важни нюансиможе да се види в таблицата.


Важно е да се вземе предвид фактът, че номерирането на щифтовете за функцията analogRead() е различно. И на третия щифт има издърпващ резистор с номинална стойност 1,5 kOhm, тъй като се използва в USB.

Няколко думи за дисплея
Може да се използва всякакъв дисплей за домашно приготвени продукти, но авторът се спря на евтин вариант. За да направи устройството още по-евтино, дисплеят може да бъде напълно изоставен. Данните могат просто да бъдат изведени към компютър чрез кабел. Тук ще е необходимо. Разглежданият дисплей е копие на дисплея.
Как изглежда дисплеят отпред и отзад може да се види на снимката.




Тъй като разстоянията между цифрите са еднакви, при изключено двоеточие, цифрите се четат без проблеми. Стандартната библиотека е в състояние да извежда числа в диапазона 0-9. букви в диапазона a-f, като има и възможност за промяна на яркостта на целия дисплей. Стойностите на цифрите могат да се задават с помощта на функцията на дисплея (int 0-3, int 0-15).


Как да използвате дисплея

// 1. Декларирайте заглавен файл
#включи
// 2. Поставете щифтове
#define CLK 0
#define DIO 1
// 3. Деклариране на обект
TM1637 tm1637 (CLK, DIO);
// 4. Инициализирайте
void setup()(
tm1637.init();
tm1637.set(6); // Яркост
}
// 5. Използвайте
void loop() (
// Показване на числото x на дисплея
int x = 1234;
tm1637.display(0, x / 1000);
tm1637.display(1, x / 100% 10);
tm1637.display(2, x / 10% 10);
tm1637.display(3, x % 10);
забавяне (500);
}

Ако се опитате да надхвърлите стойностите, тогава дисплеят ще покаже объркване, което, плюс всичко останало, не е статично. Ето защо, за да покажете специални знаци, като градуси, минуси и т.н., ще трябва да бъркате.


Авторът искаше дисплеят да показва крайната енергия на полета на куршума, която да се изчислява в зависимост от скоростта на куршума и неговата маса. Както е планирано, стойностите ​​трябваше да се показват последователно и за да се разбере къде е кой е, те трябва да бъдат маркирани по някакъв начин, например с буквата „J“. В краен случай можете просто да използвате двоеточие, но това не подхождаше на автора и той влезе в библиотеката. В резултат на това на базата на функцията за показване е направена функцията setSegments(byte addr, byte data), която осветява сегменти, кодирани в данни на фигурата с номера на адреса:


{
tm1637.start();
tm1637.stop();
tm1637.start();
tm1637.writeByte(addr|0xc0);
tm1637.writeByte(данни);
tm1637.stop();
tm1637.start();
tm1637.stop();
}

Такива сегменти се кодират доста просто, битът с ниски данни е отговорен за горния сегмент, а след това по посока на часовниковата стрелка, 7-ият бит е отговорен за средния сегмент. Знакът "1", когато е кодиран, изглежда като 0b00000110. Осмият най-значим бит е отговорен за дебелото черво, използва се във втората цифра и се игнорира във всички останали. Впоследствие авторът автоматизира процеса на получаване на кодове с помощта на Excel.


Какво се получи в крайна сметка, можете да видите на снимката




#включи
#define CLK 0
#define DIO 1
TM1637 tm1637 (CLK, DIO);

void setSegments(byte addr, byte data)
{
tm1637.start();
tm1637.writeByte(ADDR_FIXED);
tm1637.stop();
tm1637.start();
tm1637.writeByte(addr|0xc0);
tm1637.writeByte(данни);
tm1637.stop();
tm1637.start();
tm1637.writeByte(tm1637.Cmd_DispCtrl);
tm1637.stop();
}

void setup()(
tm1637.init();
tm1637.set(6);
}

void loop() (
// Изход Здравейте
setSegments(0, 118);
setSegments(1, 121);
setSegment(2, 54);
setSegments(3, 63);
забавяне (500);
}



И накрая, сензорите

Точна информация за сензорите не е предоставена, известно е само, че имат дължина на вълната от 940 nm. По време на експериментите е установено, че сензорите не са в състояние да издържат на ток над 40 mA. Що се отнася до захранващото напрежение, то не трябва да е по-високо от 3,3V. Що се отнася до фототранзистора, той има леко прозрачен корпус и реагира на светлина.


Нека започнем да сглобяваме и настройваме домашен продукт:

Стъпка първа. Сглобяване

Всичко е сглобено по много проста схема. От всички щифтове ще са необходими само P0, P1 и P2. Първите две се използват за дисплея, а P2 е необходим за работа на сензорите.
Както можете да видите, един резистор се използва за ограничаване на тока за светодиодите, докато вторият дърпа P2 към земята. Поради факта, че фототранзисторите са свързани паралелно, когато куршумът премине пред който и да е оптрон, напрежението в P2 ще спадне. За да определите скоростта на куршум, трябва да знаете разстоянието между сензорите, да измерите две токови удари и да определите времето, през което са се случили.
Поради факта, че ще се използва само един щифт, няма значение от коя страна да стреляте. Фототранзисторите така или иначе ще забележат куршума.










Всичко е сглобено от детайлите, които се виждат на снимката. За да събере всичко, авторът реши да използва макет. След това цялата конструкция за здравина се запълва с горещо лепило. Сензорите се поставят върху тръбата и към тях се запояват проводници.
За да предотврати пулсирането на диодите при захранване от захранваща банка, авторът инсталира 100 uF електролит успоредно със светодиодите.




Също така е важно да се отбележи, че P2 щифтът е избран по някаква причина, факт е, че P3 и P4 се използват в USB, така че сега с помощта на P2 е възможно да се флашне домашен продукт след сглобяване.
P2 също е аналогов вход, така че няма нужда да се използва прекъсване. Можете просто да измерите показанията между текущата и предишната стойност, ако разликата стане над определен праг, това означава, че в този момент куршумът просто минава близо до оптрона.

Стъпка втора. фърмуер

Prescaler е честотен делител, в стандартни случаи в платки като Arduino е 128. Тази цифра влияе колко често се анкетира ADC. Тоест за стандартните 16 MHz излиза 16/128 = 125 kHz. Всяко цифровизиране се състои от 13 операции, така че щифтът може да бъде запитан при максимална скорост от 9600 kHz. На практика това е не повече от 7 kHz. В резултат на това интервалът между измерванията е 120 μs, което е твърде дълго за домашна работа. Ако куршумът лети със скорост от 300 m / s, той ще покрие разстояние от 3,6 см през това време, тоест контролерът просто няма да може да го забележи. За да работи всичко правилно, интервалът между измерванията трябва да бъде най-малко 20 µs. За да направите това, стойността на делителя трябва да бъде равна на 16. Авторът е направил делител на 8, как се прави това може да се види по-долу.
Хареса ли ви статията? Сподели го