Велокомпьютер своими руками |
Это статья о том, как можно самостоятельно сделать для любимого велосипеда компьютер. Покупать готовый это для меня не интересно, хотя быстро, без мороки и имеет более человеческий вид. Хотелось сделать полезную вещь применив свои знания. Так вот, посмотрев в интернете несколько вариантов таких самоделок, быстро была составлена схема устройства...
В качестве основы был взят распространенный контроллер 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 секунд не было срабатывания датчика то индикатор выключается для экономии батарей. При срабатывании геркона индикатор начинает показывать скорость. Если в этом режиме кнопку нажать и подержать несколько секунд, то включится фонарь. Для выключения нужно еще раз длительно нажать кнопку. Второй режим это отображение суточного пробега в км. Если в этом режиме длительно нажать на кнопку то суточные показания обнуляются, они так же обнуляются при выключении питания. Третий режим это отображение пройденного пути, это значение храниться в энергонезависимой памяти, и при выключении питания не стирается. Обнулить эти показания можно только перепрошивкой контроллера. |
|
|
Комментарии
RSS лента комментариев этой записи.