Самодельный велокомпьютер, или как Arduino на улицу попал


    Здравствуй, Хабр! Мне хотелось бы поделиться историей о создании велокопомпьютера своими руками. После покупки велосипеда я решил как-то фиксировать свой прогресс, но мобильные трекеры оказались не самым удобным решением, а из Китая ко мне уже летел заранее заказанный там BOGEER 823, что делало покупку на месте бессмысленной. Поэтому я решил попытаться сделать велокомп своими руками, заодно заложив в него основу для расширения: управление обвесом велосипеда (передний и задний свет, звонок).

    Немного подготовки


    В основе любого велокомпьютера — геркон, который фиксирует оборот колеса, а всё остальное это элементарная математика… Конечно, я поискал в интернете готовые реализации и формулы, которые мне понадобятся.
    Как я уже писал, всё завязано на геркон: магнит зафиксирован на спице, а сам геркон на «вилке». Когда магнит на вилке замыкает геркон — это значит, что колесо сделало полный оборот и велосипед проехал расстояние равное:
    2*Pi*Rшины

    Первая версия


    Прежде всего я составил список того, что мне было нужно от велокомпьютера:
    • Текущая скорость
    • Дистанция текущей поездки
    • Дистанция всех поездок
    • Время в поездке
    • Текущее время
    • Подсветка
    • Возможность обмена данным с компьютером через карту памяти


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

    • Arduino nano
    • Nokia 5110 LCD (синяя подсветка, через GND)
    • Распаянные часы DS1302
    • Модуль SD карт


    Я быстро собрал бутерброд: сверху экран, вторым слоем SD модуль и сама ардуинка, а часы под всем этим. Получилось довольно компактно. Конечно, если бы я использовал не готовые модули, а «рассыпуху» и травил платы, можно было бы выиграть много места.

    Фото результата



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

    Убедившись в работоспособности конструкции, я решил провести первый тест. Питание я планировал от нескольких АА батареек или аккумулятора, но в тот момент под рукой их не оказалось… Поверьте, кататься на велосипеде с ноутбуком под мышкой то ещё удовольствие.
    Фото с первого теста



    Угадайте, почему не велосипед не едет назад?


    Тестирование принесло свои плоды. Я обнаружил ошибку в логике: сигнал от геркона всегда приравнивался к обороту колеса (если прошло минимальное время на оборот). Вроде, всё правильно, но если остановиться, зафиксировав магнит напротив геркона, то программа считала, что вы едете очень быстро.

    Вторая версия


    Немного доработав программу, я собрал «блок питания»: набор из пяти АА батареек. До этого я попытался использовать крону, но её для Ардуинки с обвесом оказалось мало.

    Так как мой 5110-й был на красной подложке, а значит, подсветка в нём управлялась логическим нулём, а не единицей, от программного управления через аналоговый порт пришлось отказаться и добавить простую кнопку.
    Кроме того, аналоговый порт без данных выдавал случайные значения, но это решилось простым резистором. А вот другой сюрприз от аналогового порта заставил меня поломать голову: значение замыкания геркона при питании от батареек были не такими, как при использовании USB порта.

    Фото со второго теста







    Второй тест показал уже полную работоспособность системы. Единственной проблемой стала ошибка в расчётах: радиус «26 дюймового колеса» оказался «13.5» дюймов. В результате одометр немного врал (спасибо Яндекс.Картам за удобный инструмент для расчёта расстояний).

    Третья версия


    Устройство работало, но конечно хотелось придать законченность внешнему виду. Так уж получилось, что всё что мне удалось найти — только один корпус, и он оказался «узким».

    Пара миллиметров



    Пришлось изменить расположение компонентов: в корпус всё влезло, но итоговый размер стал больше. В процессе перепайки пришлось заменить Arduino Nano и SD модуль: паяльником я владею так себе и часть выводов просто привёл в негодность.

    Размеры: 72x50x28mm
    Напильником тоже пришлось поработать...







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

    В таком виде компьютер я не оставлю. Предстоит шлифовка и покраска





    Моя торопливость сыграла злую шутку: я недостаточно хорошо зафиксировал провода под экраном и один из них стал пускать помехи (на самом деле это влияние на параметр «контрастность»).

    Лечится простым постукиванием, как в старых телевизорах




    Ещё пара исправлений в коде, и интерфейс был приведён к финальному (на текущий момент) виду.

    Устройство в сборе

    1. Скорость (Км/Ч)
    2. Одометр (Дистанция в метрах)
    3. Время поездки (В минутах)
    4. Текущее время (По Москве)



    Неприятность преподнесли часы: один из контактов отошёл, и время стало скакать (как если бы я перепутал RST и CLK). Но что самое интересное — после поездки часы пришли в норму.

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

    Почти вертикальный крепёж



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

    Итоговый вариант








    Стоимость


    • Корпус BOX-G020 — 115р
    • Эпоксилин — 95р
    • Батарейки — 60р
    • Arduino Nano — 120р
    • Nokia LCD 5110 — 102р
    • Чёрная изолента — 40р
    • SD module — 187р
    • DS1302 — 70р
    • Кейсы для батареек — 120р
    • Провода и резисторы — 80р
    • Геркон + магнит — 82р


    Итого: ~1100р

    Ссылки по теме




    Итоги


    Я получил ещё немного опыта работы с Arduino и сборки небольших работающих устройств. Весело провёл несколько часов, но что самое главное — теперь у меня есть работающий велокомпьютер. В планах написать нормальное сохранение/загрузку «глобальных» данных на карту памяти и добавить кнопку для отображения «глобальной» статистики. Для управления внешними устройствами у меня осталось шесть аналоговых портов (три кнопки & три тиристора) и где-то затерялся один цифровой, например, для дальномера (парктроник) или градусника. Очень хотелось бы решить проблему с питанием, ибо пять АА батареек на раме велосипеда не очень смотрятся.
    Котейка, которая помогала тестировать велокомп



    Код скетча
    #include <SD.h>
    #include <DS1302.h>
    
    //Function: This procedure applies to the Arduino driver NOKIA 5110 LCD.
    //Time:September 4,2012
    #define PIN_SCE   3
    #define PIN_RESET 2
    #define PIN_DC    4
    #define PIN_SDIN  5
    #define PIN_SCLK  6
    
    #define reed A0//
    
    #define LCD_C     LOW
    #define LCD_D     HIGH
    int count=0;
    char dat[4];
    char disp_tab[]={
      '0','1','2','3','4','5','6','7','8','9'};
    #define LCD_X     84
    #define LCD_Y     48
    const int chipSelect = 10;
    static const byte ASCII[][5] =
    {
      {
        0x00, 0x00, 0x00, 0x00, 0x00  } // 20  
      ,{
        0x00, 0x00, 0x5f, 0x00, 0x00  } // 21 !
      ,{
        0x00, 0x07, 0x00, 0x07, 0x00  } // 22 "
      ,{
        0x14, 0x7f, 0x14, 0x7f, 0x14  } // 23 #
      ,{
        0x24, 0x2a, 0x7f, 0x2a, 0x12  } // 24 $
      ,{
        0x23, 0x13, 0x08, 0x64, 0x62  } // 25 %
      ,{
        0x36, 0x49, 0x55, 0x22, 0x50  } // 26 &
      ,{
        0x00, 0x05, 0x03, 0x00, 0x00  } // 27 '
      ,{
        0x00, 0x1c, 0x22, 0x41, 0x00  } // 28 (
      ,{
        0x00, 0x41, 0x22, 0x1c, 0x00  } // 29 )
      ,{
        0x14, 0x08, 0x3e, 0x08, 0x14  } // 2a *
      ,{
        0x08, 0x08, 0x3e, 0x08, 0x08  } // 2b +
      ,{
        0x00, 0x50, 0x30, 0x00, 0x00  } // 2c ,
      ,{
        0x08, 0x08, 0x08, 0x08, 0x08  } // 2d -
      ,{
        0x00, 0x60, 0x60, 0x00, 0x00  } // 2e .
      ,{
        0x20, 0x10, 0x08, 0x04, 0x02  } // 2f /
      ,{
        0x3e, 0x51, 0x49, 0x45, 0x3e  } // 30 0
      ,{
        0x00, 0x42, 0x7f, 0x40, 0x00  } // 31 1
      ,{
        0x42, 0x61, 0x51, 0x49, 0x46  } // 32 2
      ,{
        0x21, 0x41, 0x45, 0x4b, 0x31  } // 33 3
      ,{
        0x18, 0x14, 0x12, 0x7f, 0x10  } // 34 4
      ,{
        0x27, 0x45, 0x45, 0x45, 0x39  } // 35 5
      ,{
        0x3c, 0x4a, 0x49, 0x49, 0x30  } // 36 6
      ,{
        0x01, 0x71, 0x09, 0x05, 0x03  } // 37 7
      ,{
        0x36, 0x49, 0x49, 0x49, 0x36  } // 38 8
      ,{
        0x06, 0x49, 0x49, 0x29, 0x1e  } // 39 9
      ,{
        0x00, 0x36, 0x36, 0x00, 0x00  } // 3a :
      ,{
        0x00, 0x56, 0x36, 0x00, 0x00  } // 3b ;
      ,{
        0x08, 0x14, 0x22, 0x41, 0x00  } // 3c <
      ,{
        0x14, 0x14, 0x14, 0x14, 0x14  } // 3d =
      ,{
        0x00, 0x41, 0x22, 0x14, 0x08  } // 3e >
      ,{
        0x02, 0x01, 0x51, 0x09, 0x06  } // 3f ?
      ,{
        0x32, 0x49, 0x79, 0x41, 0x3e  } // 40 @
      ,{
        0x7e, 0x11, 0x11, 0x11, 0x7e  } // 41 A
      ,{
        0x7f, 0x49, 0x49, 0x49, 0x36  } // 42 B
      ,{
        0x3e, 0x41, 0x41, 0x41, 0x22  } // 43 C
      ,{
        0x7f, 0x41, 0x41, 0x22, 0x1c  } // 44 D
      ,{
        0x7f, 0x49, 0x49, 0x49, 0x41  } // 45 E
      ,{
        0x7f, 0x09, 0x09, 0x09, 0x01  } // 46 F
      ,{
        0x3e, 0x41, 0x49, 0x49, 0x7a  } // 47 G
      ,{
        0x7f, 0x08, 0x08, 0x08, 0x7f  } // 48 H
      ,{
        0x00, 0x41, 0x7f, 0x41, 0x00  } // 49 I
      ,{
        0x20, 0x40, 0x41, 0x3f, 0x01  } // 4a J
      ,{
        0x7f, 0x08, 0x14, 0x22, 0x41  } // 4b K
      ,{
        0x7f, 0x40, 0x40, 0x40, 0x40  } // 4c L
      ,{
        0x7f, 0x02, 0x0c, 0x02, 0x7f  } // 4d M
      ,{
        0x7f, 0x04, 0x08, 0x10, 0x7f  } // 4e N
      ,{
        0x3e, 0x41, 0x41, 0x41, 0x3e  } // 4f O
      ,{
        0x7f, 0x09, 0x09, 0x09, 0x06  } // 50 P
      ,{
        0x3e, 0x41, 0x51, 0x21, 0x5e  } // 51 Q
      ,{
        0x7f, 0x09, 0x19, 0x29, 0x46  } // 52 R
      ,{
        0x46, 0x49, 0x49, 0x49, 0x31  } // 53 S
      ,{
        0x01, 0x01, 0x7f, 0x01, 0x01  } // 54 T
      ,{
        0x3f, 0x40, 0x40, 0x40, 0x3f  } // 55 U
      ,{
        0x1f, 0x20, 0x40, 0x20, 0x1f  } // 56 V
      ,{
        0x3f, 0x40, 0x38, 0x40, 0x3f  } // 57 W
      ,{
        0x63, 0x14, 0x08, 0x14, 0x63  } // 58 X
      ,{
        0x07, 0x08, 0x70, 0x08, 0x07  } // 59 Y
      ,{
        0x61, 0x51, 0x49, 0x45, 0x43  } // 5a Z
      ,{
        0x00, 0x7f, 0x41, 0x41, 0x00  } // 5b [
      ,{
        0x02, 0x04, 0x08, 0x10, 0x20  } // 5c ¥
      ,{
        0x00, 0x41, 0x41, 0x7f, 0x00  } // 5d ]
      ,{
        0x04, 0x02, 0x01, 0x02, 0x04  } // 5e ^
      ,{
        0x40, 0x40, 0x40, 0x40, 0x40  } // 5f _
      ,{
        0x00, 0x01, 0x02, 0x04, 0x00  } // 60 `
      ,{
        0x20, 0x54, 0x54, 0x54, 0x78  } // 61 a
      ,{
        0x7f, 0x48, 0x44, 0x44, 0x38  } // 62 b
      ,{
        0x38, 0x44, 0x44, 0x44, 0x20  } // 63 c
      ,{
        0x38, 0x44, 0x44, 0x48, 0x7f  } // 64 d
      ,{
        0x38, 0x54, 0x54, 0x54, 0x18  } // 65 e
      ,{
        0x08, 0x7e, 0x09, 0x01, 0x02  } // 66 f
      ,{
        0x0c, 0x52, 0x52, 0x52, 0x3e  } // 67 g
      ,{
        0x7f, 0x08, 0x04, 0x04, 0x78  } // 68 h
      ,{
        0x00, 0x44, 0x7d, 0x40, 0x00  } // 69 i
      ,{
        0x20, 0x40, 0x44, 0x3d, 0x00  } // 6a j 
      ,{
        0x7f, 0x10, 0x28, 0x44, 0x00  } // 6b k
      ,{
        0x00, 0x41, 0x7f, 0x40, 0x00  } // 6c l
      ,{
        0x7c, 0x04, 0x18, 0x04, 0x78  } // 6d m
      ,{
        0x7c, 0x08, 0x04, 0x04, 0x78  } // 6e n
      ,{
        0x38, 0x44, 0x44, 0x44, 0x38  } // 6f o
      ,{
        0x7c, 0x14, 0x14, 0x14, 0x08  } // 70 p
      ,{
        0x08, 0x14, 0x14, 0x18, 0x7c  } // 71 q
      ,{
        0x7c, 0x08, 0x04, 0x04, 0x08  } // 72 r
      ,{
        0x48, 0x54, 0x54, 0x54, 0x20  } // 73 s
      ,{
        0x04, 0x3f, 0x44, 0x40, 0x20  } // 74 t
      ,{
        0x3c, 0x40, 0x40, 0x20, 0x7c  } // 75 u
      ,{
        0x1c, 0x20, 0x40, 0x20, 0x1c  } // 76 v
      ,{
        0x3c, 0x40, 0x30, 0x40, 0x3c  } // 77 w
      ,{
        0x44, 0x28, 0x10, 0x28, 0x44  } // 78 x
      ,{
        0x0c, 0x50, 0x50, 0x50, 0x3c  } // 79 y
      ,{
        0x44, 0x64, 0x54, 0x4c, 0x44  } // 7a z
      ,{
        0x00, 0x08, 0x36, 0x41, 0x00  } // 7b {
      ,{
        0x00, 0x00, 0x7f, 0x00, 0x00  } // 7c |
      ,{
        0x00, 0x41, 0x36, 0x08, 0x00  } // 7d }
      ,{
        0x10, 0x08, 0x08, 0x10, 0x08  } // 7e ←
      ,{
        0x78, 0x46, 0x41, 0x46, 0x78  } // 7f →
    };
    
    void LcdCharacter(char character)
    {
      LcdWrite(LCD_D, 0x00);
      for (int index = 0; index < 5; index++)
      {
        LcdWrite(LCD_D, ASCII[character - 0x20][index]);
      }
      LcdWrite(LCD_D, 0x00);
    }
    
    void LcdClear(void)
    {
      for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
      {
        LcdWrite(LCD_D, 0x00);
      }
    }
    
    void LcdInitialise(void)
    {
      pinMode(PIN_SCE, OUTPUT);
      pinMode(PIN_RESET, OUTPUT);
      pinMode(PIN_DC, OUTPUT);
      pinMode(PIN_SDIN, OUTPUT);
      pinMode(PIN_SCLK, OUTPUT);
      digitalWrite(PIN_RESET, LOW);
      digitalWrite(PIN_RESET, HIGH);
      LcdWrite(LCD_C, 0x21 );  // LCD Extended Commands.
      LcdWrite(LCD_C, 0xB1 );  // Set LCD Vop (Contrast). 
      LcdWrite(LCD_C, 0x04 );  // Set Temp coefficent. //0x04
      LcdWrite(LCD_C, 0x14 );  // LCD bias mode 1:48. //0x13
      LcdWrite(LCD_C, 0x0C );  // LCD in normal mode.
      LcdWrite(LCD_C, 0x20 );
      LcdWrite(LCD_C, 0x0C );
    
    }
    
    void LcdString(char *characters)
    {
      while (*characters)
      {
        LcdCharacter(*characters++);
      }
    }
    
    void LcdWrite(byte dc, byte data)
    {
      digitalWrite(PIN_DC, dc);
      digitalWrite(PIN_SCE, LOW);
      shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
      digitalWrite(PIN_SCE, HIGH);
    }
    void gotoXY(int x, int y)
    {
      LcdWrite( 0, 0x80 | x);  // Column.
      LcdWrite( 0, 0x40 | y);  // Row. 
    }
    
    
    void dispcountt(int count)
    {
      LcdCharacter(disp_tab[count/10000]);
      LcdCharacter(disp_tab[count/1000%10]);
      LcdCharacter(disp_tab[count/100%10]);
      LcdCharacter(disp_tab[count%100/10]);
      LcdCharacter(disp_tab[count%10]);
    }
    
    //storage variables
    float radius = 13.5;//Радиус шины в дюймах. У 26 дюймовой шины, около 13.5 (магия)
    
    boolean reedVal;
    long timer = 0;//Время между оборотами в миллисекундах
    float kmh = 0.00;//Скорость в км/ч
    float circumference;
    
    float distance = 0;//Дистанция поездки в метрах
    
    long totalDistance = 0;//Дистанция всех поездок в метрах
    long totalTime = 0;//Время всех поездок в минутах
    float distanceBuffer = 0;//Несохранённая дистанция поездки в метрах
    long timeBuffer = 0;//Несохранённое время поездки в секундах
    
    float deltaD;//Проезжаем за оборот в метрах
    boolean moving = false; //флаг - едем или нет
    long time = 0;//Время езды в секундах
    long lastTime = millis();
    long duration = 0;
    
    DS1302 rtc(9, 8, 7);
    
    int maxReedCounter = 100;//Минимальное время в миллисекундах на оборот
    int reedCounter;
    
    
    void setup(void)
    {
      rtc.halt(false);
      rtc.writeProtect(false);
      
      pinMode(10, OUTPUT);//Магия для карты памяти
      
      reedCounter = maxReedCounter;
      deltaD = 2*3.415926535*radius*0.025;//Проезжается за один оборот колеса в метрах
      circumference = 2*3.14*radius;//То же самое, но с меньшей точностью (для измерения скорости) и не в метрах
      pinMode(A0, INPUT);
      
      // TIMER SETUP- the timer interrupt allows preceise timed measurements of the reed switch
      //for mor info about configuration of arduino timers see http://arduino.cc/playground/Code/Timer1
      cli();//stop interrupts
    
      //set timer1 interrupt at 1kHz
      TCCR1A = 0;// set entire TCCR1A register to 0
      TCCR1B = 0;// same for TCCR1B
      TCNT1  = 0;
      // set timer count for 1khz increments
      OCR1A = 1999;// = (1/1000) / ((1/(16*10^6))*8) - 1
      // turn on CTC mode
      TCCR1B |= (1 << WGM12);
      // Set CS11 bit for 8 prescaler
      TCCR1B |= (1 << CS11);   
      // enable timer compare interrupt
      TIMSK1 |= (1 << OCIE1A);
      
      sei();//allow interrupts
      //END TIMER SETUP
      
      LcdInitialise();
      LcdClear();
        
      LcdString("Initializing SD card...");
      pinMode(10, OUTPUT);
      gotoXY(0, 1);
      if (!SD.begin(chipSelect)) {
         LcdString("Card failed, or not present");
      }else{
         LcdString("Card initialized.");
         File logFile = SD.open("logfile.txt");
         if (logFile)
      {
        gotoXY(0, 2);
        LcdString("reading file");
         while (logFile.available()) {
         totalDistance = logFile.parseInt();
         totalTime = logFile.parseInt();
         }
      } else {
        gotoXY(0, 2);
        LcdString("error read file");
      } 
      }
      
      
      LcdClear();
      gotoXY(0, 0);
      LcdString("Spd:");//скорость Км/Ч
      gotoXY(0, 1);
      LcdString("Dst:");//дистанция за поездку в метрах
      gotoXY(0, 2);
      LcdString("Drt:");//длительность поездки в минутах
      gotoXY(0, 3);
      LcdString("Clc:");//часы
    }
    
    
    ISR(TIMER1_COMPA_vect) {//Прерывание на частота 1 кГц для проверки геркона
      if(analogRead(reed) >= 680 && analogRead(reed) <= 742){//Геркон замкнут при таких показаниях
        reedVal = true;
      }else{
        reedVal = false;
      }
    
    if (reedVal){//Геркон замкнут
    
    if (timer > 110){
       moving = true;
    }
    
    if (reedCounter == 0){//Минимальное время между импульсами прошло
         if(moving){
          kmh = (56.8*float(circumference))/float(timer)*1.61;//километры в час
          distance += deltaD;
          distanceBuffer
          }
          reedCounter = maxReedCounter;//Сбрасываем reedCounter
          timer = 0;//Сбрасываем таймер геркона
      } else{
          if (reedCounter > 0){//Не улетаем в минуса
            reedCounter -= 1;//Уменьшаем reedCounter
          }
        }
      }else{//Если геркон не замкнут
        if (reedCounter > 0){//Не улетаем в минуса
          reedCounter -= 1;//Уменьшаем reedCounter
        }
      }
      if (timer > 2000){
        kmh = 0;//Если долго нет сигналов от геркона, мы стоим.
        moving = false;
      }else{
        timer += 1;//Увеличиваем таймер
      } 
    }
    
    void updateDisplay(){
      for(int i = 0; i<=3; i++){
      gotoXY(28, i);
      LcdString("        ");
      }
      
      char Sensor1CharMsg[8]; 
    
    
      gotoXY(28, 0);
      if(moving){
      String Sensor1String((int)(kmh), DEC);
      Sensor1String.toCharArray(Sensor1CharMsg,(Sensor1String.length()+1));
      LcdString(Sensor1CharMsg);
      }else{
      LcdString("0");
      }
      LcdString("KM/h");
      
      gotoXY(28, 1);
      String Sensor1String2((int)(distance), DEC);
      Sensor1String2.toCharArray(Sensor1CharMsg,(Sensor1String2.length()+1));
      LcdString(Sensor1CharMsg);
      LcdString("m");
      
      gotoXY(28, 2);
      String Sensor1String3((int)(duration/60), DEC);
      Sensor1String3.toCharArray(Sensor1CharMsg,(Sensor1String3.length()+1));
      LcdString(Sensor1CharMsg);
      LcdString("min");
      
      gotoXY(28, 3);
      String Sensor1String4(rtc.getTimeStr(FORMAT_SHORT));
      Sensor1String4.toCharArray(Sensor1CharMsg,(Sensor1String4.length()+1));
      LcdString(Sensor1CharMsg);
    }
    
    
    void loop(void)
    {
      if (reedVal){//Геркон замкнут
    if (timer <= 110){
      moving = false;//Мы остановились, замкнув геркон
    }else{
       moving = true;
    }
      }
      updateDisplay();
      saveData();
      
      if (moving){
      int d = (int)((millis()-lastTime)/1000)
      timeBuffer += d;
      duration += d;
      }
      
      lastTime = millis();
      
      delay(1000);
    }
    
    void saveData(){
    while(timeBuffer>=60){
     timeBuffer-=60;
     totalTime++;
    } 
    while(distanceBuffer>=11){
     distanceBuffer-=11;
     totalDistance+=11;
    } 
    
    }
    
    Поделиться публикацией
    Никаких подозрительных скриптов, только релевантные баннеры. Не релевантные? Пиши на: adv@tmtm.ru с темой «Полундра»

    Зачем оно вам?
    Реклама
    Комментарии 89
    • +3
      Осталось еще один геркон к педалям прикрепить, чтобы уж полный комплект был)
      • 0
        Это чтобы считать «мои» обороты? Не подумал, если честно.
        Но уж совсем обвешивать велосипед проводами не хочется, уже сейчас получается громоздко…
        • +1
          Знать каденс очень полезно, можно, ради оригинальности, рассчитывать его, установив датчики положения манеток.
          Есть и еще парочка направление расширения функционала — подключение датчика ЧСС и пульсоксиметра.
        • 0
          Каденс обязательно нужен. Если уж делать такйой троллейбус — то только с каденсом.
        • 0
          Сейчас я пережил небольшую аварию. Думаю, что поворотники нужнее: показывать поворот водителю руками — травмоопасно.
          • +6
            Не поможет, в 70% случаев водители не обращают внимания на велосипедистов… Тем более что у них там мигает…
            Я по этому езжу только по тротуарам(( Ибо крайний правый ряд почти всегда утыкан дебилами, которым лень проехать 10 метров до парковочного кармана(

            Лучше купить шлем)
            • +1
              Мне теперь нужны новые тормоза, шорты и переключатель скоростей. Боюсь, что до шлема дело дойдёт только к следующему лету. А я всего лишь хотел показать водителю куда поворачиваю.
              • +7
                Получается, что в аварии были виноваты вы и водитель вам ничего не возместил?
                Лучше купить шлем и ездить в рваных шортах, чем без шлема и в новых.
                Я вот за 2.5 года ежедневной езды на работу по Москве 3 раза попадал в мелкие дтп по вине водителей и пешеходов, один раз почти приложился виском об асфальт, так что без шлема бы я мог получить неплохое сотрясение.
                Для себя я уяснил — совершать маневр надо только тогда, когда убедился, что другие участники движения понимают твой маневр, а не когда вы показали поворот и при этом соблюдаете пдд, ведь водитель запросто может считать, что ему можно не соблюдать пдд рядом с велосипедистом.
                • 0
                  Ну я езжу по тротуарам обычно. Но есть места в городе где их просто нет. Аварией я бы это не назвал: просто я улетел на обочину и покорёжил обвес велосипеда.
                  • +4
                    Как скутерист с 8-летним стажем в прошлом могу сказать одно, если бы не экипировка, которая в нашем мотоклубе является чем-то вроде трусов, без которых вообще на улице даже появляться стыдно, соклубники вообще заплюют, без нее я не писал бы сейчас эти строки. В среднем двухколесник (за всех не берусь сказать, но я и мои друзья в основном по ДОП катаем) как минимум 1 раз в год, но раскладывается, и зачастую не из-за своих косяков. Мой совет — прислушайтесь, что вам про шлем говорят и наколенники и перчатки — тоже очень спасают! Шорты можно одеть любые — голову не переоденешь! Сейчас пересел на вел полностью со скутера — очень многое надо с мототехники перенимать на вел, понимаю это на своей пятой точке часто видя как у нас водят остальные участники движения, и как ходят те, кто думает, что пешеходная дорожка только для них. Печальная статистика на личных примерах — минимальная скорость, при которой был летальный случай — 15км/час, банальный удар головой без шлема об бордюр пассажира. Это не придумано.
                    • 0
                      Спасибо. После починки велосипеда озабочусь покупкой обмундирования.
                      Но для меня велосипед это летнее средство передвижения, сугубо по тротуарам.
            • +8
              Не поможет, т.к. водитель не ожидает увидеть у велосипеда поворотники, и попросту не среагирует на них. Более того, в случае разбора ДТП вы еще и окажетесь не правы, т.к. по ПДД для велосипедистов предусмотрены исключительно жесты руками, никаких мигающих лампочек.
              А вот шлем лучше купить ASAP, хотя бы безымянный китайский за полторы тысячи, иначе в следующий раз новые тормоза, шорты и прочее могут уже не понадобиться.
              • 0
                Не помню, чтобы в ПДД было написано про обозначение поворотов именно велосипедистами. Там вроде как общие правила действуют (есть поворотники — используешь их, нет или сломались — показываешь рукой).

                А так да, надёжнее руками показывать.
                • 0
                  Есть определенные правила оборудования техники габаритными и сигнальным огнями. В правилах этих пояснений нет, но вот, например, квадриками многими нельзя пользоваться на ДОП именно потому, что у них неправильная светотехника. При разборах в суде это будет легко установлено экспертизой, и станет только отягчающим моментом! Поэтому — поставить мигалку поворотов и даже стоп-сигнал можно, но надеяться, что это будет основой для водятла, который уберет тебя с дороги — нет!
                  • 0
                    В ПДД это довольно чётко описано (раздел 8, пункт 1). Вопрос ещё в том, что манёвр можно обозначать одной рукой. Я обычно левую руку держу на тормозе, поэтому показываю правой: вытянутая вправо — поворот направо, согнута в локте и направлена вверх — налево.
                    • +2
                      Показывать левый поворот правой рукой — абсолютно безнадёжно. ПДД в этом плане далеки от реальности.
                      • 0
                        Всегда было интересно, как тормозя «в пол» обоими ручными тормозами обозначить при этом маневр. 8.2 на эту тему говорит «заблаговременно» и «закончить непосредственно перед началом маневра». Тут собственно даже других участников движения не надо, сам уберешься.
                        И да, шлем, очки и яркий задний фонарь обязательно. Где-бы стоп-сигнал еще раздобыть на гидравлику…
                    • 0
                      Кстати почему до сих пор не изобрели мигающие стрелки на самих велоперчатках? Ведь это же очевидное решение — показываешь поворот рукой + еще мигающая стрелка с тыльной стороны ладони дублирует и привлекает внимание
                      • 0
                        У вас появилась идея для стартапа.
                        • 0
                          Лепим на перчатку стрелку из светоотражайки и вращая рукой можно заставить ее «мигать» :)
                          • +1
                            Вы реализовали идею для стартапа :D
                            • +1
                              Отражайка, имеючи катафотную микроструктуру, всегда отражает свет туда, откуда он пришёл, независимо от угла поворота (ну, в определённых пределах).
                              Так что крутить придётся градусов на 90.
                              • 0
                                Ну это не сложно. Я это и имел ввиду. Или в ладонь и сжимать разжимать пальцы :)
                            • 0
                              C Arduino LilyPad такое сделали года два назад, только вшили в спину велокостюма. Ссылку сейчас не найду, простите.
                              Но нужно учитывать, что это было в США, у них другие ПДД =)
                              • 0
                                Если честно, не очень понимаю зачем там Arduino. Почему не хватит просто отражайки?
                                • 0
                                  Потому что нужно, чтобы стрелки работали, как фары автомобиля — ярко мигали, но только когда велосипедист включает поворотник. т.е. нажимает на кнопку.
                              • 0
                                Я как-то хотел такое реализовать, только в виде браслетов, т.к. в перчатках ездить не люблю… Но слишком громоздко выходило (хотя при должном умении можно, конечно, сделать компактно), не люблю лишним обвешиваться при катании… А ночью можно и просто светоотражающие полоски на запястья вешать.
                            • +1
                              На руки можно надевать ленточки из светоотражайки. Водители нормально реагируют.
                          • +1
                            Прикольно конечно, но вообще буханка.jpg www.dx.com/c/sports-outdoors-1699/cycling-1607/bike-computer-1645

                            Как учебный проект\проект для души — ОК!
                            • +1
                              Я себе заказал BOGEER 823, но придёт он ещё фиг знает когда…
                            • +5
                              Синяя изолента — Спасенье навеки моё
                              И инженера-студента
                              Представить нельзя без неё
                              Если случайно поранясь
                              Пластыря нет под рукой
                              Синюю изоленту
                              Срочно наклей и не ной.
                              Трещины в стенах повсюду?
                              По швам разошелся мой дом?
                              Её же наклеивать буду
                              Нет мысли о чем-то другом.
                              И только когда с проводкой
                              Хреново. Случилась беда
                              Воспользуйся просто смоткой
                              Экономь изоленту всегда!

                              © Copyright: Евгений Шевнин
                              • +2
                                Вы видимо, зашли сюда только ради этого комментария? )
                                Советую взглянуть вам на фото в конце поста. Там… Чёрная изолента.
                                • –1
                                  Против чёрной я тоже ничего не имею.
                                  • +1
                                    Сейчас, пережил падение. Чёрная изолента не выдержала и блок с батарейками отправился в полёт. Экран просто переносило. Весь бок разодран, а на уме ваша песенка :/
                                    • НЛО прилетело и опубликовало эту надпись здесь
                                      • +1
                                        Ещё когда читал пост, подумал, что замена синей изоленты на чёрную негативно скажется на надёжности устройства. И верно.
                              • +1
                                Ещё не говорили о силе Синей Изоленты! :)
                                • +1
                                  Автор показал, что Сила Черной тоже не слаба! ;-)
                                • +2
                                  Не понял про запитку подсветки дисплея — в чем сложность подать на аналоговый выход 0? На худой конец для инвертора один транзистор, два резистора нужно.
                                  • 0
                                    Ну одно дело подать прямо с контакта 1, а другое, делать инвертор )
                                    Просто поставил тумблер.
                                    • 0
                                      Подавайте всегда единицу, когда надо подсветку включить — ноль. Разница только в коде. Да и транзистор припаять — не сложнее кнопки.
                                      • 0
                                        Ну просто после этого всеравно придется припаять кнопку, чтобы сообщить контроллеру, что вы изволите подсветку включить или выключить.
                                        • 0
                                          Типа в инвертированном случае это делать не надо?
                                          • 0
                                            Дак я так понял, автор просто прилепил выключатель напрямки между источником питания и выводом экранчика ответсвенным за подсветку.
                                • +3
                                  Опыт полезный, но реализация топорная)
                                  Вот тут человек тоже свой велокомпьютер делает
                                  • 0
                                    Топорная, кто ж спорит, зато куча положительных эмоций.
                                    Спасибо за ссылку: я думал что все подобные материалы нашёл. Но там реализация совсем на ином уровне: сбор из компонентов, собственная плата и корпус с 3D принтера.
                                    • 0
                                      Эмоции в таком деле, пожалуй, самое главное. А по поводу корпуса, небезызвестный DIHALT считает, что корпус самое интересное в таком деле, надеюсь вы свою поделку тоже до ума доведете
                                      • 0
                                        Ну у него 3D принтер, а у меня напильник…
                                        Не уверен, что можно сравнить наши ощущения от плодоводства корпуса.
                                        • +1
                                          У меня нет принтера. Я бы из ассортимента Gainta подобрал.

                                          А вообще выкинуть все эти потроха, спаять нормальную плату и все на ней развести. Будет в 3 раза компактней и надежней.
                                          • 0
                                            Приветсвую.
                                            Полностью с вами согласен, но боюсь, что веселье от сборки исчезнет, зато будет множество проблем с пайкой. Я умею паять, но хотелось бы пропустить этот уровень и заняться более интересными делами. А то, учитывая мой опыт, я как раз к зиме закончу =)
                                            Хотя, как знать, может я таки куплю утюг и открою эту статью.
                                            • 0
                                              Не ссать! Не будет никаких проблем. Берешь и делаешь. Потом сам будешь удивляться чего так долго тупил.

                                              Там возни то на один день. За день пройдешь все стадии освоения технологии.
                                              • 0
                                                Я стараюсь трезво оценивать свои силы, чтобы не получить кучу недоделанных проектов. Переход на самостоятельную травлю вызовет кучу других переводов. Например, зачем тогда использовать Arduino? Можно взять «голый» процессор. Зачем использовать C? Assembler forever! И всё в таком духе. Но конечно, я не отказываюсь от этой идеи: раньше платы уже травил, хоть и не совсем самостоятельно.
                                                P.S. Компактнее, кстати будет в четыре раза. Все микросхемы можно будет уместить под экраном: SD заменить на MicroSD, а DS1XXX вообще распять, оставив только место для батарейки. Найти процессор с питанием от 3V и тогда получится спрятать аккумулятор в основном корпусе, а не выносить.
                                                • 0
                                                  От ардуино можно оставить среду и библиотеки. Да они кривые, но зато готовые. Собственно вы сейчас тратите дохренища времени на то чтобы спаять всю эту лапшу и потом еще косяки ловите. Это будет упрощение процесса, а не переход к большему хардкору.
                                • +3
                                  Совет автору и будущим авторам: от того, что вы прячете картинки под спойлер трафик жрать они не перестают, а вот чтение статьи как раз заставляет будто-бы заново собрать ваш «велокомпьютер» :)
                                  • 0
                                    а почему геркон, а не датчик Холла, катушка или оптопара?
                                    • 0
                                      Первое, что пришло в голову и самое простое в реализации (на мой взгляд).
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                        • 0
                                          Чем сложен датчик Холла?
                                          • 0
                                            Чем геркон. Шутка.

                                            Сложнее он тем, что у него 4 выхода, с которым надо разобраться, сигнал с холла в лучшем случае надо на АЦП подать, а в худшем еще через усилитель пропустить. А если хочется счетчик на железном прерывании сделать, что довольно логично и просто, может еще компаратор потребоваться. А геркон, он как бы проще некуда — нужен он и резистор подтяжки. Ну по мне — абсолютно нет смысла туда ставить холл, потому что никаких выгод это не принесет в текущем виде. Теоретически, им можно обратных ход колеса детектить, но для велосипеда это настолько редкая ситуация, что практически ее смысла поддерживать нет. Лучше поставить еще один датчик на педали.
                                            • 0
                                              Пардон, но вам ли не знать про пороговые датчики холла, которые выдают не аналоговый сигнал на выходе, а лог. единицу в случае, если магнитное поле есть? И почему 4 выхода, когда у Ханивеловских — три: плюс, минус и лог. выход. А из преимуществ имеет гарантированное срабатывание, не зависящее от скорости (мой прошлый велокомп отказывался показывать) больше 60 кмч, магнит слишком быстро проскакивал перед герконом, тот не успевал замыкаться), отсутствие механических частей, и, как следствие, отсутствие дребезга контактов и необходимости его обрабатывать.
                                              • 0
                                                Да как-то вот совсем холл оказался неуместен в велокомпах.
                                                Найдите хоть один промышленный с чем-то отличным от геркона — удивлюсь!
                                                • 0
                                                  И правда не знал. Вот, если кто захочет просветиться. Стоят тоже не очень дорого, сравнимо с герконом.
                                                  Но, как уже сказали ниже, требуется питание(хотя в случае с неоптимизированным кодом для ардуины это не особо критично), да и провода тащить надо уже 3, а не два. Я бы геркон взял.
                                                • 0
                                                  Холлу ещё в конечном итоге чемодан батареек потребуется :)
                                                  Расточительно это — при батарейном питании пускать ток в какой-то датчик, при том что есть абсолютно ничего не потребляющая альтернатива (геркон).
                                            • 0
                                              Потому что это самый простой и экономичный вариант.
                                              Герконы используются как на велокомпе, что на полуторавольтовой «таблетке» работает годами независимо от погоды, так и на достаточно крутых гарминовских датчиках скорости/каденса. Холл и оптопара требуют питания. Катушка не всегда желательна (геркон меньше).
                                            • 0
                                              я так понимаю у вас будет приклееный магнит? почему бы тогда не использовать два магнита и два геркона? таким образом максимальная скорость не уменьшается а показания с герконов дают возможность обрабатывать такие ошибки как мы стоим а он считает. просто магниты расположить по разным сторонам колёса.
                                              • 0
                                                Лучше магнит и индуктивную катушку. И ловить импульсы наведенные.
                                                • 0
                                                  Еще и батарейку заряжать от катушки :)
                                              • 0
                                                а экипировка вещь необходимая, я на мотоцикле раньше катался, если бы не экипировка то не уверен что жив был, и если бы был то без руки и парализованный.
                                                • 0
                                                  Так как мой 5110-й был на красной подложке, а значит, подсветка в нём управлялась логическим нулём, а не единицей, от программного управления через аналоговый порт пришлось отказаться и добавить простую кнопку.


                                                  Не совсем понятно. Что мешало сделать analogWrite(contrastPin, 255 — contrastValue)?
                                                  • 0
                                                    Я опечатался. Не нулём, а землёй.
                                                    Это же не одно и тоже? Если одно, то я дурак.
                                                    • 0
                                                      Нет-нет, в данном случае, мне кажется, не опечатались, Если говорить про логические сигналы на входе\выходе у МК, то тут используются именно «ноль»\«единица». Если говорить о физических сигналах, то обычно используют «питание»\«земля». Эти две группы понятий, естественно, тесно связаны — если вы подключите Input — пин микроконтроллера к земле и попытаетесь считать значение, на нем будет ноль, а если к питанию, то единица.
                                                      И не дурак, а только учитесь =)
                                                  • +2
                                                    Круто, и с синей изолентой!
                                                    Но… вы не задумывались над тем, что ардуина тут немного излишня?
                                                    Для прототипа или эксперимента — да, легко.
                                                    Но вот в реальной жизни таскать кучу плат и ведро батареек только ради возможности «слить» данные поездки в комп — имхо, излишне.
                                                    Посмотрите на практически любой велокомп. Стоит в минимуме баксов 5-6. Работает несколько лет от алкалиновой «таблетки».
                                                    Единственное — данные поездки придётся переписывать с него вручную.
                                                    (а много ли важных данных? Дистанция, время в пути, время стоянок, максимальная скорость. И всё?)

                                                    Да, и про длину колеса: погуглите, таблички длины окружности в зависимости от параметров покрышки существуют.
                                                    У 26-дюймового колеса 26 дюймов — это обод. А популярные покрышки на таком ободе, начиная от узких (дюйм) до широких (2,35 дюйма) дадут существенно разные цифры!
                                                    • 0
                                                      Спасибо про инфу про колёса )

                                                      А про остальное я в этой ветке писал.
                                                      • +1
                                                        Если хотите поточнее выяснить длину окружности колеса — то нужно:
                                                        1. накачать колеса штатным давлением
                                                        2. сделать мелом вертикальную метку на покрышке
                                                        3. раскрутить по прямой рулетку, прижав чем-нибудь, чтобы не сворачивалась
                                                        4. сесть на вел (самому, вес важен!), сориентировав его вдоль рулетки меткой вниз, запомнить начальную цифру
                                                        5. прокатить строго вдоль рулетки точно на один оборот колеса (это делать лучше с помощником)
                                                        6. собственно, вычислить длину окружности по разнице двух меток :)

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

                                                        Для велосипеда зависимостью от скорости можно пренебречь, но привести радиус (или путь одного оборота — ясное дело, неважно) к реальным условиям эксплуатации — тому давлению, до которого вы обычно качаете колеса, и весу самого седока — очень даже желательно. Если все сделаете правильно — получите погрешность не более нескольких метров на километр.
                                                        • +1
                                                          Лучше всего выставить приблизительно диаметр — а потом проехать по ровной местности прямой отрезок существенной длины (от километра до десяти).
                                                          Точную длину отрезка измерить с помощью gps (с нынешним повсеместным распространением смартфонов это не проблема!) А дальше просто подправить длину колеса пропорционально замеченной разнице (благо зависимость линейная, считать легко).

                                                          Если есть возможность, можно все то же сделать с прибором Garmin серии Edge и датчиком вращения. В нем просто ставим длину колеса = auto и ездим некоторое время, пока он не запищит и не скажет, что колесо выставлено (делает ровно то же — сопоставляет импульсы вращения с геоданными gps и выставляет длину).
                                                    • 0
                                                      Очень интересно, но подобная приборная панель для велосипеда стоит в районе 500 рублей, можно было бы купить и не париться :)
                                                      • 0
                                                        Подобная «приборная панель» едет ко мне из Китая, о чём я писал в самом начале.
                                                      • +2
                                                        Это сейчас все просто — берется практически любой МК, минимум обвязки, блок индикации тоже готовый с уже встроенным контроллером — только код пиши. И то народ на ассемблере уже не хочет, и паяет с ленцой — все больше смотрят на готовые eval-борды да скетчи

                                                        А когда я в 88м году делал велоспидометр для своего Старт-Шоссе — иначе, как на россыпи было не сделать. У меня был спроектирован аппарат с тремя функциями — текущая скорость, максимальная скорость, пройденный путь, автоотключение ЖК при долгой остановке, сброс пути и максималки. Все вместе потянуло на пару десятков (!) корпусов 176 и 561 серии. Индикатор — 4-разрядный ЖК со статической индикацией (дефицит, между прочим был). Все размещалось на двух платах-слепышах одна над другой и индикатором сверху. Для компактности по высоте ИМС в дипах были распаяны псевдо-планарно — с отгибанием выводов в плоскость платы, монтаж — ПЭВТЛ (с залуживанием прямо во время пайки), питание — от четырех Д-0.1. Все вместе помещалось в нижнюю половину мыльницы :) размером примерно 100 * 70 * 25, с лицевой панелью из полированного оргстекла заподлицо. В стендбае конструкция потребляла всего порядка 3 микроампер, на ходу — порядка десятков, и могла жить целый сезон от одной зарядки.

                                                        Кстати, это сейчас программно можно подсчитать период и преобразовать его в скорость — а в устройстве на ИМС малой степени интеграции это было невозможно — попробуйте-ка выполнить деление на счетчиках и сдвиговых регистрах :). В итоге, приходилось считать частоту импульсов — а для того, чтобы время счета было приемлемым, на ступицу ставился не один магнит, а шесть (!). Но геркон, да был — действительно, самый экономичный вариант, как не требующий входных аналоговых активных компонентов — только пассивную схему антидребезга

                                                        • +1
                                                          Я проще делал. Китайский калькулятор, параллельно кнопке Равно подключался геркон, в калькулятор вводилась длинна окружности колеса, нажимался плюсик и поехали. Скорость не показывало, но одометр был. =)
                                                          • 0
                                                            Одометр — да. Похожую идею видел в самодельном станке для намотки трансформаторов — там тоже использовался калькулятор в качестве счетчика количества намотанных витков.
                                                            • 0
                                                              Только не всякий калькулятор.
                                                              Некоторые настолько тормозные, что не успевают. И потому показания отстают.
                                                          • 0
                                                            в начале статьи ожидал увидеть какие-то наработки, которые помогут собрать умное освещение для ночных покатушек, но теперь понимаю, что проще купить готовое [паять умею, но это но это не моя сильная сторона] )
                                                            ну и по поводу обмундирования полностью согласен с высказываниями выше. видимо чужой опыт не учит, так как сам тоже не пользовался защитой пока не свалился с вела по своей же неосмотрительности
                                                            • 0
                                                              Жаль, что вас разочаровал.
                                                              Моё освещение ещё не пришло, да и текущие размеры основного модуля не устраивают. Умное освещение хотел сделать с помощью тиристора и фоторезистора
                                                              Только что вышел из веломагазина
                                                            • 0
                                                              Продолжение статьи заморожено.
                                                              Сегодня велосипед угнали.
                                                              • 0
                                                                Сочувствую. Как это произошло? Какие средства защиты использовали?
                                                                • 0
                                                                  В университете срезали прямо с парковки.
                                                                  Камеры не работают, был простой велозамок, но толстый. (не Uшка)

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