RSS блога
Подписка
Серая коробочка радиодеталей. Хронометр для пневматики своими руками
- Цена: 2,99
- Перейти в магазин
Владею пневматической винтовкой, всегда была интересна скорость вылета пули из ствола, это кому-то покажется странным, но у пневмолюбов скорость пули одна из главных тем для членометрии. Погуглив немного нашел несколько вариантов схем на разных микроконтроллерах, так как у меня уже был опыт работы с AVR, без раздумий выбрал вариант на avr. Все необходимые детали я нашел на упоминавшемся уже здесь Taydaelectronics.com. Покупка собрана, оплачена, получена, приступим…
Сразу приложу схему:
поподробнее желающие могут посмотреть на сайте автора.
Итак, нам понадобится:
Микроконтроллер attiny 2313 — 1 шт.
Регулятор напряжения L7805 — 1 шт.
Пара конденсаторов 330 нФ и 100нФ для регулятора напряжения
(можно запитать всю схему от трех пальчиковых батареек вместо кроны, тогда регулятор и конденсаторы не понадобится)
Подстроечный резистор на 20-50 килоом 2 шт.
7-сегментный индикатор на три цифры с общим катодом 1 шт.
УФ светодиод 2 шт.
Фототранзистор 2 шт.
выключатель, панелька для микроконтроллера, панелька для индикатора, коннекторы для шлейфов, сам шлейф я использовал от старого компьютера. Так же набор резисторов.
КОРОБОЧКА!!!
Вот все компоненты запаяны на плату, осталось только прошить микроконтроллер
ОНО ЖИВОЕ!
После этого я изготовил измерительную трубку с датчиками. Устроено просто — на расстоянии 50 мм друг от друга находятся расположенные друг напротив друга фототранзистор и светодиод, своеобразные оптопары. Когда пулька пролетает по трубке, она поочередно перекрывает луч света первому и второму транзистору, о чем они сигналят микроконтроллеру, который высчитывает скорость по всем известной со школы формуле.
напильником и ручным лобзиком придал нужную форму коробочке, распихал всю начинку по местам, закрепив где необходимо термосоплями.
Приступим к стрельбам:
Винтовка на фото — Stoeger x20, в который установлена газовая пружина. В теории может выжать 250 м/с.
И он почти выжал пулькой 0.68 грамм
Устройство готово, и работоспособно.
Конечно же я не рассчитываю на его точность, эталона рядом не было, но скорость показывает не рандомно, стабильно. Если нужно отслеживать изменение начальной скорости пули в зависимости от изменений конструкции пневматики, то этого вполне достаточно. Аналоги такого хронометра стоят более 2 тысяч рублей, этот же обошелся мне не более чем в 300р, и еще подарил 4 часа приятного времяпрепровождения.
Сразу приложу схему:
поподробнее желающие могут посмотреть на сайте автора.
Итак, нам понадобится:
Микроконтроллер attiny 2313 — 1 шт.
Регулятор напряжения L7805 — 1 шт.
Пара конденсаторов 330 нФ и 100нФ для регулятора напряжения
(можно запитать всю схему от трех пальчиковых батареек вместо кроны, тогда регулятор и конденсаторы не понадобится)
Подстроечный резистор на 20-50 килоом 2 шт.
7-сегментный индикатор на три цифры с общим катодом 1 шт.
УФ светодиод 2 шт.
Фототранзистор 2 шт.
выключатель, панелька для микроконтроллера, панелька для индикатора, коннекторы для шлейфов, сам шлейф я использовал от старого компьютера. Так же набор резисторов.
КОРОБОЧКА!!!
Повторил схему в протеусе, подогнал под свои нужды, и вытравил печатную плату
добавил разъемов в схему
кое-как расставил компоненты, чтобы иметь примерное представление, как рисовать дорожки. И да, у меня нет принтера, я рисую дорожки перманентным маркером)))
сначала пробую на бумаге
потом переношу на текстолит
Травим. Травлю в горячем растворе хлорного железа, разведенного примерно 1:3 с водой. После травления раствор храню на балконе, он работает даже после высыхания, нужно просто добавить воды. Следует осторожничать и не допускать попадания его на металлические поверхности — начнется усиленная коррозия.
Чистим
Сверлим. Дрельку делал из патрона и моторчика с фасттека.
кое-как расставил компоненты, чтобы иметь примерное представление, как рисовать дорожки. И да, у меня нет принтера, я рисую дорожки перманентным маркером)))
сначала пробую на бумаге
потом переношу на текстолит
Травим. Травлю в горячем растворе хлорного железа, разведенного примерно 1:3 с водой. После травления раствор храню на балконе, он работает даже после высыхания, нужно просто добавить воды. Следует осторожничать и не допускать попадания его на металлические поверхности — начнется усиленная коррозия.
Чистим
Сверлим. Дрельку делал из патрона и моторчика с фасттека.
Вот все компоненты запаяны на плату, осталось только прошить микроконтроллер
ОНО ЖИВОЕ!
После этого я изготовил измерительную трубку с датчиками. Устроено просто — на расстоянии 50 мм друг от друга находятся расположенные друг напротив друга фототранзистор и светодиод, своеобразные оптопары. Когда пулька пролетает по трубке, она поочередно перекрывает луч света первому и второму транзистору, о чем они сигналят микроконтроллеру, который высчитывает скорость по всем известной со школы формуле.
исходный код
/*
* Прошивка без наворотов, расстояние между датчиками 100мм
* общий анод!
* Updated at: 15.12.2013
* Author: pahan
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define LED_EMPTY ~0b00000000
#define LED_0 ~0b00111111
#define LED_1 ~0b00000110
#define LED_2 ~0b01011011
#define LED_3 ~0b01001111
#define LED_4 ~0b01100110
#define LED_5 ~0b01101101
#define LED_6 ~0b01111101
#define LED_7 ~0b00000111
#define LED_8 ~0b01111111
#define LED_9 ~0b01101111
#define LED_DOT ~0b10000000
#define LED_MINUS ~0b01000000
#define LED_E ~0b01111001
#define LED_r ~0b01010000
#define LED_G ~0b00111101
#define LED_o ~0b01011100
#define BASE_LENGTH 1000
typedef struct LedPanel {
int seg1;
int seg2;
int seg3;
} LedPanel;
LedPanel led;
void renderSegmentNext() {
static int activeSegment = 0;
activeSegment = (activeSegment + 1) % 3;
switch (activeSegment) {
case 0:
PORTB = led.seg1;
PORTD = ~0b0110000;
break;
case 1:
PORTB = led.seg2;
PORTD = ~0b1010000;
break;
case 2:
PORTB = led.seg3;
PORTD = ~0b1100000;
break;
}
}
void initPorts() {
//init led ports
DDRB = 0xFF;
DDRD |= (0b111 << 4);
//init button ports
DDRD &= ~(1 << PD0);
DDRD &= ~(1 << PD1);
}
int digitToLedValue(int digit) {
switch (digit) {
case 0:
return LED_0;
case 1:
return LED_1;
case 2:
return LED_2;
case 3:
return LED_3;
case 4:
return LED_4;
case 5:
return LED_5;
case 6:
return LED_6;
case 7:
return LED_7;
case 8:
return LED_8;
case 9:
return LED_9;
default:
return LED_MINUS;
}
}
void setLedValue(int value) {
if(value < 0 || value > 400){
led.seg1 = LED_MINUS;
led.seg2 = LED_MINUS;
led.seg3 = LED_MINUS;
return;
}
led.seg3 = digitToLedValue(value % 10);
if (value >= 10) {
led.seg2 = digitToLedValue((value / 10) % 10);
} else {
led.seg2 = LED_EMPTY;
}
if (value >= 100) {
led.seg1 = digitToLedValue((value / 100) % 10);
} else {
led.seg1 = LED_EMPTY;
}
}
ISR( TIMER1_OVF_vect ) {
//stop timer and reset value
TCCR1B &= ~(1 << CS00);
TCNT1 = 0;
//disable int1
GIMSK &= ~(1 << INT1);
//set error output
setLedValue(-1);
}
ISR(INT0_vect) {
//reset timer and start it
TCNT1 = 0;
TCCR1B |= (1 << CS00);
//enable int1
GIMSK |= 1 << INT1;
}
ISR(INT1_vect) {
//stop timer
TCCR1B &= ~(1 << CS00);
//disable int1
GIMSK &= ~(1 << INT1);
//calculate speed
int speed = (F_CPU / 10000L) * BASE_LENGTH / TCNT1;
setLedValue(speed);
}
int main() {
initPorts();
MCUCR |= (1 << ISC00);
MCUCR |= (1 << ISC01);
GIMSK |= 1 << INT0;
MCUCR |= (1 << ISC10);
MCUCR |= (1 << ISC11);
GIMSK &= ~(1 << INT1);
TIMSK |= (1 << TOIE1);
sei();
setLedValue(0);
while (1) {
renderSegmentNext();
_delay_ms(2);
}
}
* Прошивка без наворотов, расстояние между датчиками 100мм
* общий анод!
* Updated at: 15.12.2013
* Author: pahan
*/
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define LED_EMPTY ~0b00000000
#define LED_0 ~0b00111111
#define LED_1 ~0b00000110
#define LED_2 ~0b01011011
#define LED_3 ~0b01001111
#define LED_4 ~0b01100110
#define LED_5 ~0b01101101
#define LED_6 ~0b01111101
#define LED_7 ~0b00000111
#define LED_8 ~0b01111111
#define LED_9 ~0b01101111
#define LED_DOT ~0b10000000
#define LED_MINUS ~0b01000000
#define LED_E ~0b01111001
#define LED_r ~0b01010000
#define LED_G ~0b00111101
#define LED_o ~0b01011100
#define BASE_LENGTH 1000
typedef struct LedPanel {
int seg1;
int seg2;
int seg3;
} LedPanel;
LedPanel led;
void renderSegmentNext() {
static int activeSegment = 0;
activeSegment = (activeSegment + 1) % 3;
switch (activeSegment) {
case 0:
PORTB = led.seg1;
PORTD = ~0b0110000;
break;
case 1:
PORTB = led.seg2;
PORTD = ~0b1010000;
break;
case 2:
PORTB = led.seg3;
PORTD = ~0b1100000;
break;
}
}
void initPorts() {
//init led ports
DDRB = 0xFF;
DDRD |= (0b111 << 4);
//init button ports
DDRD &= ~(1 << PD0);
DDRD &= ~(1 << PD1);
}
int digitToLedValue(int digit) {
switch (digit) {
case 0:
return LED_0;
case 1:
return LED_1;
case 2:
return LED_2;
case 3:
return LED_3;
case 4:
return LED_4;
case 5:
return LED_5;
case 6:
return LED_6;
case 7:
return LED_7;
case 8:
return LED_8;
case 9:
return LED_9;
default:
return LED_MINUS;
}
}
void setLedValue(int value) {
if(value < 0 || value > 400){
led.seg1 = LED_MINUS;
led.seg2 = LED_MINUS;
led.seg3 = LED_MINUS;
return;
}
led.seg3 = digitToLedValue(value % 10);
if (value >= 10) {
led.seg2 = digitToLedValue((value / 10) % 10);
} else {
led.seg2 = LED_EMPTY;
}
if (value >= 100) {
led.seg1 = digitToLedValue((value / 100) % 10);
} else {
led.seg1 = LED_EMPTY;
}
}
ISR( TIMER1_OVF_vect ) {
//stop timer and reset value
TCCR1B &= ~(1 << CS00);
TCNT1 = 0;
//disable int1
GIMSK &= ~(1 << INT1);
//set error output
setLedValue(-1);
}
ISR(INT0_vect) {
//reset timer and start it
TCNT1 = 0;
TCCR1B |= (1 << CS00);
//enable int1
GIMSK |= 1 << INT1;
}
ISR(INT1_vect) {
//stop timer
TCCR1B &= ~(1 << CS00);
//disable int1
GIMSK &= ~(1 << INT1);
//calculate speed
int speed = (F_CPU / 10000L) * BASE_LENGTH / TCNT1;
setLedValue(speed);
}
int main() {
initPorts();
MCUCR |= (1 << ISC00);
MCUCR |= (1 << ISC01);
GIMSK |= 1 << INT0;
MCUCR |= (1 << ISC10);
MCUCR |= (1 << ISC11);
GIMSK &= ~(1 << INT1);
TIMSK |= (1 << TOIE1);
sei();
setLedValue(0);
while (1) {
renderSegmentNext();
_delay_ms(2);
}
}
напильником и ручным лобзиком придал нужную форму коробочке, распихал всю начинку по местам, закрепив где необходимо термосоплями.
Приступим к стрельбам:
Винтовка на фото — Stoeger x20, в который установлена газовая пружина. В теории может выжать 250 м/с.
И он почти выжал пулькой 0.68 грамм
Устройство готово, и работоспособно.
Конечно же я не рассчитываю на его точность, эталона рядом не было, но скорость показывает не рандомно, стабильно. Если нужно отслеживать изменение начальной скорости пули в зависимости от изменений конструкции пневматики, то этого вполне достаточно. Аналоги такого хронометра стоят более 2 тысяч рублей, этот же обошелся мне не более чем в 300р, и еще подарил 4 часа приятного времяпрепровождения.
Самые обсуждаемые обзоры
+68 |
3179
131
|
+49 |
3429
64
|
+28 |
2356
43
|
+33 |
2601
34
|
+52 |
1970
37
|
Переверните фотодиоды :)
Вот в протеусе фототранзисторы верно нарисованы
Фотодиоды всегда работают при обратном напряжении на них
P.S. Я в этой теме нуб и хочу разобраться
это не придирки, а попытка по советовать сделать прибор безопасным
Вполне можно значительно увеличить сечение измерительного прохода, если чуть усложнить оптическую систему и дополнительно усилить сигнал с фототранзистора. Если в проходе прямоугольного сечения сверху и снизу проложить два строго параллельных зеркала, то запущенный в такую систему под небольшим углом сфокусированный световой луч образует в сечении прохода световую преграду. При этом, прерывание летящей пулей светового луча в любой точке — вызовет появление сигнала на фотоприёмнике. Как-то так:
Дальше целое поле для творчества, Например, расфокусировать луч по оси, находящейся в плоскости преграды, сократив при этом количество отражений и усилив ставший более слабым импульс на выходе фотоприёмника, или вообще применить вместо светодиода лазерный диод, дающий не точку, а линию…
Расфокусировка не поможет, потому что если луч будет шире пульки, прерывания светового потока не будет :)
А это просто коробка
Перефразируя общение в секс-чатах — «Хочу вставить в него своего Крюгера!!!»
Автору плюс в обзор за прямые руки :))
хороший у тебя радиорынок. у меня только коробочка 150 стоит, по 10р за диоды, 25 за кнопочку, разъемы, у них 20р миниджек стоит, а под шлейф я боюсь даже думать. ну и микроконтроллеров у них нет, и 150 за штуку попросили бы точно
Что и каким образом будет при этом калиброваться? :)
То есть с простой калибровкой, идущей с завода, этот генератор обеспечивает +-10% от заявленной частоты при определенном питании и температуре. Прользуясь танцами с бубном его можно заставить повысить точность до +-2% при неизменном напряжении питания и температуре. Перенесли девайс куда-то, где теплее или холоднее — калибровка коту под хвост и возвращаемся хорошо если к плюс-минус 10% :)
Правда проверял на атмегах
RC-генераторы просто не могут быть с точностью 0.1%, если только они не термостабилизированы и не содержат прецизионного источника опорного напряжения. Вообще всегда было принято при измерении каких-то внешних временных интервалов обязательно тактировать контроллер от внешнего кварца. В этом отношении приведенная схема безграмотна :) Но мерять относительные величины при неизменных внешних условиях ею можно :)
Кроме того калибровка требует или внешних инструментов (программатор, UART) или того же внешнего кварца. То есть по-быстрому перед очередными отстрелами ее не проведешь :)
патрон
блок питания любой, который даст 12в. 1а. сам питаю от самопального лабораторника регулируемого
Но осталось поле для работы. Замерил скорость с помощью генератора и частотомера. Оказалось, что хронограф занижает скорость на 11 %. Полагаю что это из-за несоответствия частоты внутреннего генератора расчетной 1 МГц. Впаял кварц на 4 МГц. Подскажите пожалуйста, что нужно изменить в прошивке, чтобы она учитывала кварц и коэфф. деления на 4. Ну и до кучи как подобрать расстояние между фотодиодами. Использовал самую первую прошивку на 100 мм с общим катодом. Еще раз огромное спасибо за схему.