Велокомпьютер своими руками

 

Это статья о том, как можно самостоятельно сделать для любимого велосипеда компьютер. Покупать готовый это для меня не интересно, хотя быстро, без мороки и имеет более человеческий вид. Хотелось сделать полезную вещь применив свои знания. Так вот, посмотрев в интернете несколько вариантов таких самоделок, быстро была составлена схема устройства...

 

В качестве основы был взят распространенный контроллер ATtiny2313.  Для которого и была написана программа. В качестве индикатора используется семисегментный четырехразрядный индикатор, красного свечения. Транзисторы обыкновенные маломощные NPN, в моем случае ставил КТ315.

Печатная плата изготавливалась лазерно-утюжным методом. Контроллер установил в панельку, чтобы можно было извлекать и перепрошивать, так как разъема для программирования я не предусмотрел. Однако сделал разъемы для подключения питания и датчика, чтобы можно было снимать велокомпьютер с руля.

В качестве корпуса выбор сразу пал на старую велофару, которая работала от больших батареек-боченков и светила достаточно тускло, так как там стояла лампочка накаливания.

Вместо лампочки была сразу выточена по размеру плата, куда припаяны 4 белых светодиода типа «пиранья».

В результате тестов дома, яркость показалась очень даже достаточной, но после первой же покатушки вечером, я понял что нужно все менять.

Поискав по закормам, нашел две светодиодные сборки с отражателями от нерабочих фонариков. Примеряв все это дело, решил закрепить стационарно.

Первые же ночные испытания показали, что работа ведется в правильном направлении, теперь можно было и вечером ездить. Но для большего комфорта докупил фонарик на 1 ваттном светодиоде с регулировкой пятна света, и закрепил отдельно на руле. Теперь все видно как днем (ну почти как днем), прохожие даже оборачиваются посмотреть что это на них едет )))

Самым сложным в изготовлении это устройства, было сделать магнит, который крепиться на спицу. Все мои попытки найти в продаже готовый, но без самого компьютера, оказались безуспешными. Было решено сделать самому, как говориться полный хендмейд. Нашел магнит когда-то выковырянный из старого электросчетчика. Повертев его пару минут, определился какая часть больше подойдет, и начал пилить его своим дремелем, в итоге 4 диска сточил в ноль + 2 разлетелось, магнит оказался очень прочным, его даже сверла не брали. В итоге после дня мучений магнит был готов к установке на колесо. Пластиковая стяжка для того чтобы вся эта конструкция не проворачивалась на спице. Осталось покрасить все это дело.

Следующим компонентом, который тоже нужно было сделать самому был датчик, основанный на герконе. Здесь все было просто, выточил из текстолита платку, разрезал медь где нужно, чтобы не травить, припаял геркон и провода. Потом залил все это лаком для ногтей, чтобы хоть как-то защитить от воды и грязи.  И в конце при помощи пары подкладок и пластиковых стяжек закрепил на нужном расстоянии от магнита на вилке.

 

 

 

Еще один немало важный компонент это батарейный блок. Я решил использовать три пальчиковых аккумулятора по 1.2 В в итоге имею 3.6 В – необходимый минимум для работы контроллера достигнут. Аккумуляторы размещаются в специальном батарейном блоке, который я закрепил под  сидением. В планах сшить для него сумочку на липучках, чтобы удобнее было менять аккумуляторы.

Потом осталось проложить провода по раме, и все окончательно закрепить.

Описывать программную часть не буду, так как там все достаточно понятно, и я по ходу написания оставлял комментарии.

/*****************************************************

This program was produced by the

CodeWizardAVR V1.25.8 Evaluation

Automatic Program Generator

© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.

http://www.hpinfotech.com

 

Project :

Version :

Date    : 11.07.2011

Author  : Freeware, for evaluation and non-commercial use only

Company :

Comments:

 

 

Chip type           : ATtiny2313

Clock frequency     : 8,000000 MHz

Memory model        : Tiny

External SRAM size  : 0

Data Stack size     : 32

*****************************************************/

 

#include <tiny2313.h>

#include <delay.h>

eeprom unsigned int Total,on;  //переменная в eeprom

char      Dig[10];

char Disp1, Disp2, Disp3,Disp4,k,j;  // В этих переменных хранятся цифры, которые нужно отобразить

unsigned char Num1, Num2,Num3, Num4,startFlag, MODE=1;

unsigned long int timeC=0,time=0;               // переменная хранящая значение таймера при срабатывании геркона

unsigned long int speed=0;

int distance=0,t ,TD,i=480;

 

 

 

// External Interrupt 0 service routine

interrupt [EXT_INT0] void ext_int0_isr(void)

{

// Place your code here

if (startFlag==1){

timeC=time;            // время между прерываниями

time=0;

};

startFlag=2;

}

 

// Timer 0 overflow interrupt service routine

interrupt [TIM0_OVF] void timer0_ovf_isr(void)

{

// Place your code here

time++;

}

// Declare your global variables here

 

void Display ( unsigned int Number)    // Функция выделяет цифры из четырехзначного числа

{

Num1=Num2=Num3=Num4=0;

while (Number >=1000){

Number-=1000;

Num1++;

};

 

while (Number >= 100)

{

Number -= 100;

Num2++;

}

while (Number >= 10)

{

Number -= 10;

Num3++;

}

Num4 = Number;

Disp1 = Dig[Num1];

Disp2 = Dig[Num2];

Disp3 = Dig[Num3];

Disp4 = Dig[Num4];

};

 

void Dig_init()     //кодировка цифр для индикатора

{

Dig[0] =255-63; //(a+b+c+d+e+f);   // Сейчас у нас схема с общим катодом

Dig[1] =255-6; // (b+c);

Dig[2] =255-91; // (a+b+g+e+d);

Dig[3] =255-79; // (a+b+g+c+d);

Dig[4] =255-102; // (f+g+b+c);

Dig[5] =255-109; // (a+f+g+c+d);

Dig[6] =255-125; // (a+f+g+c+d+e);

Dig[7] =255-7;  //(a+b+c);

Dig[8] =255-127; // (a+b+c+d+e+f+g);

Dig[9] =255-111; // (a+b+c+d+f+g);

}

 

void main(void)

{

// Declare your local variables here

// Crystal Oscillator division factor: 1

#pragma optsize-

CLKPR=0x80;

CLKPR=0x00;

#ifdef _OPTIMIZE_SIZE_

#pragma optsize+

#endif

 

// Input/Output Ports initialization

// Port A initialization

// Func2=In Func1=In Func0=In

// State2=T State1=T State0=T

PORTA=0x00;

DDRA=0x00;

 

// Port B initialization

// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out

// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0

PORTB=0x00;

DDRB=0xFF;

 

// Port D initialization

// Func6=Out Func5=Out Func4=Out Func3=Out Func2=In Func1=Out Func0=In

// State6=0 State5=0 State4=0 State3=0 State2=T State1=0 State0=T

PORTD=0x00;

DDRD=0x7A;

 

// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: 1000,000 kHz

// Mode: Normal top=FFh

// OC0A output: Disconnected

// OC0B output: Disconnected

TCCR0A=0x00;

TCCR0B=0x02;

TCNT0=0x00;

OCR0A=0x00;

OCR0B=0x00;

 

// Timer/Counter 1 initialization

// Clock source: System Clock

// Clock value: 7,813 kHz

// Mode: Normal top=FFFFh

// OC1A output: Discon.

// OC1B output: Discon.

// Noise Canceler: Off

// Input Capture on Falling Edge

// Timer 1 Overflow Interrupt: On

// Input Capture Interrupt: Off

// Compare A Match Interrupt: Off

// Compare B Match Interrupt: Off

TCCR1A=0x00;

TCCR1B=0x00;

TCNT1H=0x00;

TCNT1L=0x00;

ICR1H=0x00;

ICR1L=0x00;

OCR1AH=0x00;

OCR1AL=0x00;

OCR1BH=0x00;

OCR1BL=0x00;

 

// External Interrupt(s) initialization

// INT0: On

// INT0 Mode: Rising Edge

// INT1: Off

// Interrupt on any change on pins PCINT0-7: Off

GIMSK=0x40;

MCUCR=0x02;

EIFR=0x40;

 

// Timer(s)/Counter(s) Interrupt(s) initialization

TIMSK=0x02;

 

// Universal Serial Interface initialization

// Mode: Disabled

// Clock source: Register & Counter=no clk.

// USI Counter Overflow Interrupt: Off

USICR=0x00;

 

// Analog Comparator initialization

// Analog Comparator: Off

// Analog Comparator Input Capture by Timer/Counter 1: Off

ACSR=0x80;

 

delay_ms(100);

if (on==0){

Total=0;

};

on++;

 

// Global enable interrupts

#asm("sei")

Dig_init();

 

//TD=2356;

TD=Total; // запись общего расстояния из EEPROM при подаче питания

while (1)

{

 

if (startFlag==2){                              //предотвращает вывод на экран числа до первого вычисления скорости

delay_ms(1);

speed=281250/timeC;       //((1000000/256)*2/1000*36000)/timeC

startFlag=1;              //((Гц/256)*длина колеса/1000м*3600сек*10)/timeC

i++;

};

 

/*

 

if ((i==5)&&(distance<=999)){

distance++;      //расстояние суточное в десятках метров

i=0;

}

else {

if ((i==5)&&(distance==1000)){

km=50;

distance=100;

};

};

 

if ((i==50)&&(distance<=999)){

distance++;

i=0;

}

else {

if ((i==50)&&(distance==1000)){

km=500;

distance=100;

};

};

*/

 

if ((i==500)&&(distance<=999)){

distance++;      //расстояние суточное в километрах

i=0;

TD++;            // увеличиваем на 1км показания общего километража

Total=TD;        //обновляем значение в EEPROM

}

if (distance==1000) {

distance=0;

};

 

///////////////////////////////

if (PIND.0==1) {                                           //кнопка с длительным нажатием    MODE

 

 

while ((PIND.0==1) && (t<=60)) {

delay_ms(10);

t++;

};

 

if (t<=60) {

MODE++;

if (MODE>3) {

MODE=1;

};

while (PIND.0==1) {

};

}

else {

if (MODE==2){

distance=0;

while (PIND.0==1) {

PORTD.3=0;

PORTD.4=1; // десятки

PORTD.5=1;

PORTD.6=1;

PORTB=0;

};

};

if ((MODE==1)&&(PIND.1==1)){

PORTD.1=0;

}

else {

PORTD.1=1;

};

while (PIND.0==1) {

};

//};

 

};

 

};

t=0;

////////////////////////////////////

 

switch(MODE){

case 1:

Display(speed);

//Display(timeC);

Disp1=198;

break;

 

case 2:

Display(distance);

Disp1=161;

break;

 

case 3:

Display(TD);

break;

};

 

 

for (j = 0; j <= 100; j++){} // Задержка для отображения цифры

 

if (k>=3) {

k=0;

}

else  {

k++;

};

 

PORTB = 255;  //Очистка PC7, PC6, PC5

for (j = 0; j<=10; j++){} // Задержка для выключения транзистора

 

if ((time>8000)&&(MODE==1)){             //остановка таймера если велик стоит

 

TCCR0B=0x00;

speed=0;

k=4;

timeC=0;

PORTB=255;

}

else {

 

TCCR0B=0x02;

};

 

switch (k)   //вывод чисел на индикатор

{

 

case 0:

PORTD.3=0;

PORTD.4=0; // Единицы

PORTD.5=0;

PORTD.6=1;

 

PORTB =Disp4;

if(MODE==3){

PORTB.7=0;

};

 

 

break;

case 1: PORTD.3=0;

PORTD.4=0; // десятки

PORTD.5=1;

PORTD.6=0;

 

PORTB =Disp3;

if (MODE==1){

PORTB.7=0;

};

break;

 

case 2: PORTD.3=0;

PORTD.4=1; // сотни

PORTD.5=0;

PORTD.6=0;

 

PORTB =Disp2;

break;

 

case 3: PORTD.3=1;

PORTD.4=0; // тысячи

PORTD.5=0;

PORTD.6=0;

 

PORTB =Disp1;

break;

 

case 4:

PORTD.3=0;

PORTD.4=0; // отключение дисплея

PORTD.5=0;

PORTD.6=0;

break;

 

};

 

};

}

В итоге мой компьютер имеет 3 режима работы, переключение между которыми осуществляется коротким нажатием на кнопку, которая раньше служила для включения лампочки фонаря.

Изначально при подаче питания компьютер находиться в режиме отображения текущей скорости, и если в течении 5 секунд не было срабатывания датчика то индикатор выключается для экономии батарей. При срабатывании геркона индикатор начинает показывать скорость. Если  в этом режиме кнопку нажать и подержать несколько секунд, то включится фонарь. Для выключения нужно еще раз длительно нажать кнопку.

Второй режим это отображение суточного пробега в км. Если в этом режиме длительно нажать на кнопку то суточные показания обнуляются, они так же обнуляются при выключении питания.

Третий режим это отображение пройденного пути, это значение храниться в энергонезависимой памяти, и при выключении питания не стирается. Обнулить эти показания можно только перепрошивкой контроллера.

Обсуждение статьи на форуме

22.08.2011 08:57 Автор: Алексей Молчанов
 

Комментарии  

 
0 #1 01.03.2012 12:06
Молодца! Отлично все сделал!!
Цитировать
 
 
0 #2 25.04.2012 08:15
очень круто)
Цитировать
 
 
0 #3 25.10.2012 21:19
Поделитесь пожалуйста скомпилированно й прошивкой и платой. Заранее спасибо!
Цитировать
 
 
0 #4 Sgushenka95 20.04.2014 20:37
под какое колесо горное или обычное для стелса
Цитировать
 
 
0 #5 Валера 18.09.2014 06:39
Обычно чтобы индикатор хорошо просматривался днём ставят красный светофильтр.
Цитировать
 
 
0 #6 николай ... 07.04.2016 18:33
Алексей! мне понравился ваш велокомпютер. Не могли б вы изготовить на заказ? Мне нужен в автомобиль. Если можно отпишитесь.
Цитировать
 

Добавить комментарий


Защитный код
Обновить

Вредный совет

Если за вами гонится злая собака - смотрите ей в глаза и мотыляйте ногами. Вы обязательно в неё попадете!

Голосования

Я предпочитаю: