02.06.2015 18:00 Количество просмотров материала 3536 Время на чтение ~18 мин
Увеличить | Уменьшить Распечатать страницу

Как собрать вело-генератор

Как собрать вело-генератор


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

 

kak-sobrat-velo-generator1
Основа самоделки – велосипед сопряженный с двигателем, который и будет переводить ваши калории в электрический ток. А если подробнее, то вращение педалей передается на заднее колесо, которое соответственно вращает вал двигателя, вследствие этого в обмотках двигателя возникает электрический ток, который через контроллер заряда поступает на подключенный аккумулятор и «консервируется» там. К аккумулятору подключен инвертор, имеющий два выхода-розетки и два USB-выхода. Для управления и контроля всей электроники используется микроконтроллер Arduino, включающий/отключающий контроллер заряда и инвертор, а также отображающий посредством ЖК-дисплея параметры с датчиков.

Материалы и компоненты:

• Велосипедная рама с задним колесом
• Пиломатериалы и болты (для подставки)
• Велосипедный стенд для тренировок
• Мотор 24В
• Ремень от системы охлаждения
• Шкив для ремня
• Аккумулятор 12В
• Зарядное устройство DC-DC
• Инвертор DC-AC с USB-выходами и розетками
• Arduino (я использовал Leonardo, но и другие сгодятся)
• МОП-транзистор ( полевой транзистор с изолированным затвором)
• Светодиод и фотодиод
• Датчик с эффектом Холла
• ЖК-экран
• Тумблер «On/Off»
• Реле, регулятор напряжения 5В, диод, кнопки и резисторы

 

 

Шаг 1: Подставка

 

kak-sobrat-velo-generator2

kak-sobrat-velo-generator3

kak-sobrat-velo-generator4

kak-sobrat-velo-generator5

kak-sobrat-velo-generator6

Для начала сооружаем подставку передней вилки из куска фанеры 60х180см, брусков 5х10см и шпильки с гайками. Я сделал ее потому, что велосипед мне достался без переднего колеса и пришлось придумывать как его зафиксировать. Подставка поделки получилась функциональная и выдерживает напор даже самых рьяных «гонщиков».

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

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

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

 

 

Шаг 2: От генератора к аккумулятору

 

kak-sobrat-velo-generator7

kak-sobrat-velo-generator8

kak-sobrat-velo-generator9

В качестве «накопителя» можно использовать почти любую аккумуляторную батарею, я к примеру, взял 12В свинцово-кислотный аккумулятор, потому что он был под рукой. Но в любом случае нужно знать технические характеристики и условия эксплуатации выбранного аккумулятора для правильного заряда/разряда, которые можно узнать из тех.паспорта. В моем случае аккумулятор не «любит» когда напряжение повышается больше 14В, и силу тока не выше 5.4А .

Полный разряд, а также перегрузка аккумулятора может повредить его или снизить срок службы, поэтому в мозгоцепь установлен тумблер «On/Off» который предотвращает утечки тока под фантомными нагрузками, а еще установлен микроконтроллер Arduino, отображающий состояние цепи.

Естественно, что нельзя напрямую подключить аккумулятор к клеммам мотора, это попросту «убьет» аккумулятор, поэтому между ними устанавливаем контроллер заряда, который будет подавать на аккумулятор электричество тех силы тока и напряжения, которые ему требуются. Сам контроллер будет включаться при начале кручения педалей самоделки, а 3-х секундное удержание кнопки пуска контроллера проверит состояние аккумулятора, и если ему требуется зарядка, то она начнется. При остановке кручения педалей контроллер выключается.

При покупке контроллера заряда главное подобрать нужные характеристики, то есть, чтобы он работал в тех же диапазонах, что и генератор с аккумулятором. Так для моей мозгоподелки нужен контроллер, который может принимать входное напряжение до 24В и обеспечивать 14В с силой тока не более 5.4А. В основном контроллеры имеют возможность настройки параметров, поэтому я просто выставил на нем силу тока в 5А, как и требуется для моего мозгоаккумулятора.

 

 

Шаг 3: Инвертор

 

kak-sobrat-velo-generator10

kak-sobrat-velo-generator11

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

Инвертор для поделки следует покупать в соответствии с параметрами аккумулятора и рассчитанной мощностью. Так аккумулятор выдает 12В, мощность для зарядки телефона примерно 5Вт, а ноутбука 45-60Вт. Я подобрал инвертор с мощностью 400Вт, 2-мя розетками и 2-мя USB-выходами, хотя не планирую одновременно заряжать гаджетов на 400Вт.

Инвертор можно не устанавливать если вы планируете заряжать только телефон или другие USB-устройства. Тогда нужно лишь понизить напряжение от аккумулятора до 5В и «вывести» его через USB-шнур. При данном способе электричество лишний раз не преобразуется из постоянного в переменное, а затем из переменного в постоянное, но многие все же склонны доверять инвертору, чем импровизированному USB-порту.

Сам инвертор подключается просто: положительный вход инвертора к положительной клемме аккумулятора, отрицательный мозговход к отрицательной клемме. Да и работает все просто: мотор заряжает аккумулятор через контроллер заряда, аккумулятор «питает» инвертор, а тот заряжает подключенные гаджеты.

 

 

Шаг 4: Arduino и заряд батареи

 

kak-sobrat-velo-generator12

kak-sobrat-velo-generator13

kak-sobrat-velo-generator14

kak-sobrat-velo-generator15

kak-sobrat-velo-generator16

Ранее уже было сказано, что для того чтобы началась зарядка аккумулятора нужно удерживать кнопку пуска контроллера заряда в течение 3-х секунд. Это немного не удобно, особенно хлопотно объяснять порядок включения самоделки другим людям. Поэтому «взломаем» контроллер заряда и добьемся того, чтобы простое нажатие кнопки запускало всю систему и можно было просто крутить педали.

Контроллер заряда это «волшебная» коробочка, к одной стороне которой подходят положительный и отрицательные контакты от аккумулятора, а с другой подводятся провода от мотора. Все что находится «между этими сторонами» выходит за рамки этого мозгоруководства, но все же эту коробочку придется вскрыть и прикоснуться к «магии».

Кнопки подключены к схеме 5-дорожечным кабелем, и когда одна из кнопок нажата, то сигнал с пятой дорожки через эту кнопку переходит по подключенной к ней дорожки на плату. Меняем этот 5-дорожечный кабель на связку пяти обычных проводов, то есть, выпаиваем кабель и припаиваем пять проводов, на другой конец которых устанавливаем разъем через который подключим макетную плату. На этой макетной плате размещаем 4 кнопки, которыми пока не подключен микроконтроллер, будем управлять контроллером заряда.

ВАЖНО!!! Если вы решите, так же как я, оставить плату контроллера без корпуса, то обязательно организуйте теплоотвод, так как при «интенсивной» езде контроллер сильно греется.

Чтобы «научить» Arduino нажимать кнопку пуска необходимо использовать мозгореле, которое будет по сигналу микроконтроллера выдерживать 3-х секундное «нажатие» и включать контроллер. И хотя многие реле имеют встроенные диоды для защиты, я все же рекомендую установить дополнительный, чтобы избежать обратной утечки тока к контактам Arduino.

Возникает вопрос: когда Arduino должен подавать сигнала запуска? Ответ очевиден – при начале кручения педалей, иначе запускать контроллер нет смысла. Контроллер заряда не будет «заряжать» уже полную батарею, но можно лишний раз не проверять уровень заряда вручную, а переложить эту обязанность на микроконтроллер, то есть заставить его отслеживать параметры напряжения и силы тока. Для этого можно задействовать аналоговые входы Arduino, вот только они работают в пределах от 0 до 5В, в то время на клеммах батареи 11-14В, а выходах мотора от 0 до 24В, поэтому применим делители напряжения. При подключении аккумулятора для деления напряжения берем один резистор 1кОм, и второй, идущий на заземление, 2.2кОм. Тогда при максимальном напряжении 14В от аккумулятора на втором резисторе, с которого будет считываться происходить считывание, будет около 4.4В (подробнее в статье о делителях). При подключении мотора используем в делителе напряжения резисторы 1кОм и 4.7кОм, тогда при 24В от генератора Arduino будет считывать как 4.2В. Все эти измерения в коде для Arduino легко конвертировать в действительные значения.

Чтобы исключить перезарядку аккумулятора самоделки напряжение на его клеммах должно быть меньше 14В, а вот для генератора параметры более гибкие – если велосипедист «вырабатывает» напряжение достаточное для включения контроллера, то контроллер может заряжать батарею. В итоге, параметры напряжения будут таковы: от генератора больше 5В, а для аккумулятора менее 14В.

Сам микроконтроллер будет включаться через «кнопку» или что-либо подобное, так как постоянно держать его включенным не резонно. И «запитывать» его лучше не от сменной батарейки 9В, а от 12В-го аккумулятора. Для этого подключаем микроконтроллер через разъем и регулятор напряжения 5В к аккумулятору, хотя Arduino и поддерживает напряжение питания 12В. Кстати от этих 5В можно запитать еще какую-либо электронику, а не использовать для этого 5В-й пин на Arduino. Регулятор обязательно размещаем на радиаторе, так как при работе он сильно греется.

Пример кода:

// complete code at the end of this Instructable

int motor = A0; //motor/generator pin on the Arduino

int batt = A1; //12V battery pin

int cc = 8; //charge controller pin

int wait = 500; //delay in milliseconds

float afactor = 1023.0; //Arduino's analog read max value

float motorV, battV; //motor voltage and battery voltage

boolean hasBeenOn = false; //to remember if the charge controller has been turned on

void setup() {

pinMode(motor, INPUT);

pinMode(batt, INPUT);

pinMode(cc, OUTPUT);

}

void loop() {

motorV = getmotorV(); //motovr/generator output voltage

if (motorV > 1.0 && !hasBeenOn) { //if our DC motor gives out more than 1V, we say it's on

digitalWrite(cc, HIGH); //the cc pin is connected to a relay

//that acts as the "Start" button for the charge controller

delay(3500); //our charge controller requires the start button to be held for 3 seconds

digitalWrite(cc, LOW); //electrically releasing the start button

hasBeenOn = true; //the charge controller should be charging the battery now

delay(wait); //we want our Arduino to wait so not to check every few millisec

}

else if(motorV > 1.0 && hasBeenOn){

delay(wait); //again, we don't want the Arduino to check every few millisec

}

else{

hasBeenOn = false; //the person is no longer biking

}

}

//we wrote separate functions so we could organize our code

float getmotorV(){

return (float( analogRead(motor) ) / afactor * 5.0); //the motor gives out about a max of 5V

}

float getbattV(){

return (float(analogRead(batt)) / afactor * 14.0); //the battery technically is~13.5V

}

 

 

Шаг 5: Arduino и инвертор

 

kak-sobrat-velo-generator17

Держать постоянно подключенным инвертор к аккумулятору не выгодно по нескольким причинам. Во-первых, фантомная нагрузка разряжает мозгоаккумулятор, а во-вторых, нужно сделать «защиту» от хитрецов желающих подзарядить гаджет, но не желающих покрутить для этого педалей. Поэтому снова задействуем Arduino, который будет включать/выключать инвертор и тем самым контролировать выходы для зарядки, не полагаясь на честность и технические знания пользователей.

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

Замечу, что при прохождении больших токов через транзистор поделки он сильно греется, поэтому, так же как и на регулятор напряжения, установка радиатора на транзистор обязательна!

Пример кода:

//the complete code can be found at the end of this Instructable

//the bolded code is what we add to the code from above

int mosfet = 7; // used to turn on the inverter

unsigned long timeOn, timecheck; // for time checking

void loop(){

if (motorV > 1.0 && !hasBeenOn) {
timeOn = millis();

}

inverterControl();

}

// the separate function

void inverterControl() {

battV = getbattV(); //check the battery voltage

timecheck = millis() - timeOn; //check how long the user has been biking

/* We want the user to have biked for a certain amount of time

before allowing the user to charge the user's electronics.

We also need to be sure that the battery isn't undercharged.

*/

if (hasBeenOn && (battV > 10.0) && (timecheck > 5000) && !mosfetOn) {

digitalWrite(mosfet, HIGH); //the inverter is on when the Arduino turns on the MOSFET

mosfetOn = true;

}

else if ((battV <= 10.0)) { //turns off inverter if the battery is too low

digitalWrite(mosfet, LOW);

mosfetOn = false;

}

else if(timecheck <5000) { //turns off if the user stopped/hasn't biked long enough

digitalWrite(mosfet, LOW);

mosfetOn = false;

}

}

 

 

Шаг 6: Arduino и обратная информация

 

kak-sobrat-velo-generator19

kak-sobrat-velo-generator20

kak-sobrat-velo-generator21

В качестве обратной связи во время тренировки можно взять значения частоты вращения заднего колеса, то есть «велосипедист» будет не только заряжать аккумулятор, но и получать информацию об интенсивности своей тренировки. Чтобы считать обороты заднего колеса можно использовать оптический датчик и датчик Холла.

Оптический датчик

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

Схема подключения диодов тоже проста: на оба диода подается от микроконтроллера 5В, но в цепи светодиода обязательно установить резистор, так как светодиод обладает низким сопротивлением и значит ток, текущий по нему будет большим и светодиод попросту перегорит. Поэтому последовательно со светодиодом монтируем резистор 1кОм, и тогда ток по светодиоду будет течь примерно 5мА. Принцип работы фотодиода противоположен работы светодиода, то есть свет используется для получения напряжения, а не наоборот. И, следовательно, в цепи фотодиод нужно устанавливать в обратном направлении, чем светодиод. Напряжение, создаваемое фотодиодом, измеряется на резисторе подключенного после фотодиода, и величина напряжения не важна, потому что нам важно лишь прерывание луча от светодиода. Номинал резистора после фотодиода нужно подобрать таким, чтобы даже при попадании на фотодиод света от ламп освещения, напряжение будет равно 0. Путем мозгоопытов я подобрал резистор 47кОм, и при блокировке луча светодиода напряжение равно 0, а при попадании луча на фотодиод напряжение вырабатывается достаточное для считывания. Таким образом, при нулевом значении напряжения Arduino понимает, что колесо совершило одно вращение.

Датчик Холла

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

Пример кода:

//the complete code can be found at the end of this Instructable
//the bolded code is what we add to the code from above

int pdiode = A3; // photodiode for rpm

int photodiode;

int cycle = 0;

int numCycle = 20; // for averaging use

float t0 = 0.0;

float t1;

void setup() {

pinMode(pdiode, INPUT);

}

void loop() {

if (motorV > 1.0 && !hasBeenOn) {

cycle = 0;

t0 = float (millis());

}

getRpm();

}

void inverterControl() {

else if(timecheck <5000) {

cycle = 0; //this is a safety since arduino can't run multiple threads

t0 = float (millis());

}

}

void getRpm() {

//may want to consider an if else/boolean that makes sure increasing cycle only when biking

if (t0 == 0.0) { //safety for if the arduino just started and t0 hasn't been set yet

t0 = float (millis());

}

photodiode = analogRead(pdiode);

if (((photodiode != 0) && (analogRead(pdiode) == 0)) || ((photodiode == 0) && (analogRead(pdiode) != 0))) {

cycle++;

t1 = float(millis());

if (cycle > numCycle) {

rpm = (float(cycle)) / (t1 - t0)* 1000.0 * 60.0; //conversion to rotations per minute

cycle = 0;

t0 = float (millis());

}

}

 

 

Шаг 7: Arduino и датчик силы тока

 

kak-sobrat-velo-generator23

kak-sobrat-velo-generator25

kak-sobrat-velo-generator26

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

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

Пример кода:

/the complete code can be found at the end of this Instructable

//the bolded code is what we add to the code from above

int hall = A2; //for current sensing

float Wh = 0; //for recording the watt-hours generated since Arduino has been on

void setup() {

pinMode(hall, INPUT);

}

void loop() {

else if(motorV > 1.0 && hasBeenOn){

getCurrent();

}

}

void getCurrent(){ //the current going into the battery

current = (float(analogRead(hall))-514.5)/26.5; //equation for current from experimental plot

Wh = Wh + float(wait)/3600.0*current*13.0; // calculation for watt-hour

//assume 13V charge controller output into battery

}

 

 

Шаг 8: ЖК-дисплей

 

kak-sobrat-velo-generator27

Существует много вариантов вывода информации используя Arduino и ЖК-дисплей. Выбранный мной экран имеет 2 строки с 16-ю символами в каждой, 4 кнопки направления, кнопка «выбор» и кнопка «сброс». Для упрощения кодирования я использовал в коде лишь кнопки направлений, сам код довольно «сырой» с примерными значениями для многих параметров. Если вы владеете С++, то можете написать свой более профессиональный мозгокод. Я хотел чтобы «велосипедист» имел сохраненную статистику о лучшем времени одного заезда, общей дистанции, общего количества Ватт/часов с начала эксплуатации поделки. Во время заезда я планировал отображать на дисплее время заезда, скорость в км/ч, сгенерированную мощность и энергию в Ватт/часах выработанную за заезд. Если вы впервые сталкиваетесь с использованием ЖК-дисплея в своей самоделке, то полезно ознакомится вот с этим.

Рассчитать необходимые данные не трудно: для получения частоты вращения и км/с нужно разделить количество оборотов колеса на время, потраченное для совершения этого количества оборотов колеса, и перевести в соответствующие единицы измерения. Измерив радиус заднего колеса, он равен 28см, получаем длину окружности 175.929см или 0.00175929км. Далее по формуле «скорость*время=расстояние» получаем пройденное расстояние. По формуле «сила тока*напряжение» рассчитываем мощность, а для получения значения энергии с помощью суммы Риманна умножили мгновенную мощность на прошедшее время (0.5с) и прибавили каждые полсекунды вращения педалей.
Относительно меню, я проиндексировал каждое отображение и использовал фиктивную переменную для перемещения по отображениям.

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

Схема меню:

Главное Меню
> Лучшее время
>> Показать значение
> Общее расстояние
>> Показать значение
> Сгенерированная мощность
>> Показать значение
> О
>> Любая информация о велосипеде .
//Полный код можно найти в конце этого мозгоруководства

//the bolded code is what we add to the code from above

// include the library code:

#include <Wire.h>

#include <Adafruit_MCP23017.h>

#include<Adafruit_RGBLCDShield.h>

#include <EEPROM.h> //for long term information storage on Arduinos

//This portion is taking word for word from Adafruit's tutorial, which we linked above

// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore

// However, you can connect other I2C sensors to the I2C bus and share

// the I2C bus. Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

// These #defines make it easy to set the backlight color

#define RED 0x1

#define YELLOW 0x3

#define GREEN 0x2

#define TEAL 0x6

#define BLUE 0x4

#define VIOLET 0x5

#define WHITE 0x7

//here starts the part we coded

int ptr = 0; // menu pointer

int mins, secs, kmh;

//long term storage variables

int timeAddress = 0;

int distanceAddress = 1;

int powerAddress = 2;

byte timeValue, distanceValue, powerValue;

boolean isHome = true;

void setup() {

lcd.begin(16, 2);

lcd.print("Hello, world!");

lcd.setBacklight(WHITE);

timeValue = EEPROM.read(timeAddress);

distanceValue = EEPROM.read(distanceAddress);

powerValue = EEPROM.read(powerAddress);

root(); //set display to root menu

}

uint8_t i=0; // we put this in because the tutorial included it (not exactly sure what it's for)

void loop() {

menuFunction(); //see if button is pressed

if (motorV > 1.0 && !hasBeenOn) {

lcd.clear();

lcd.setCursor(0,0);

lcd.print("Warming up...");

lcd.setCursor(0,1);

lcd.print("Keep pedaling. ");

lcd.setBacklight(GREEN);

digitalWrite(cc, HIGH); //press start on charge controller

lcd.setBacklight(YELLOW);

delay(3500); //press start for 3.5 seconds

cycle = 0;

t0 = millis();

digitalWrite(cc, LOW); //stop pressing start

//battery should now be charging

lcd.clear();

lcd.setCursor(0,0);

hasBeenOn = true;

lcd.print("Charging battery");

lcd.setBacklight(RED);

lcd.setCursor(3, 1);

timeOn = millis();

//time of how long person has been pedaling

lcd.print((millis()-timeOn)/1000);

delay(wait);

isHome = false;

}

else if(motorV > 1.0 && hasBeenOn){

secs = int((millis()-timeOn)/1000);

mins = int(secs/60);

secs = int(secs%60); //this could also be written as a separate function

lcd.clear();

lcd.setCursor(0, 0);

lcd.print(mins);

lcd.setCursor(2, 0);

// print the number of seconds since start biking

lcd.print(":");

lcd.setCursor(3, 0);

lcd.print(secs);

lcd.setCursor(9, 1);

lcd.print(rpm);

lcd.setCursor(13,1);

lcd.print("RPM");

isHome = false;

getCurrent(); //this prints W, Wh

getkmh(); //this prints km/h

}

else{

if (timeValue > (millis()-timeOn/1000/60)){

timeValue = int(millis()-timeOn/1000/60);

EEPROM.write(timeAddress, timeValue);

}

if(!isHome){

root();

}

}

}

void getkmh() {

kmh = rpm*60.0*revolution;

lcd.setCursor(0, 1);

lcd.print(kmh);

lcd.setCursor(2,1);

lcd.print("km/h ");

}

void getCurrent(){

current = (float(analogRead(hall))-514.5)/26.5;

lcd.setCursor(6, 0);

lcd.print(int (current*13));

lcd.setCursor(8,0);

lcd.print("W");

Wh = Wh + float(wait)/3600.0*current*13.0;

lcd.setCursor(10,0);

lcd.print(Wh);

lcd.setCursor(13,0);

lcd.print("Wh");

}

void menuFunction() {

delay(200);

uint8_t buttons = lcd.readButtons();

if (buttons) {

if (buttons & BUTTON_UP) {

scrollUp(ptr);

}

if (buttons & BUTTON_DOWN) {

if(ptr >0){

scrollDown(ptr);

}

}

if (buttons & BUTTON_LEFT) {

if(ptr >=1 && ptr <=4){

root();

}

else if(ptr >= 5){

menu();

}

}

if (buttons & BUTTON_RIGHT) {

scrollRight();

}

}

}

void menu() {

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("MENU (scroll V)");

lcd.setCursor(0, 1);

lcd.print("Top times");

ptr = 1;

}

void root() {

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Bike to Charge!");

lcd.setCursor(0, 1);

lcd.print("Menu (Right >)");

ptr = 0;

isHome = true;

}

void scrollRight() {

Serial.println(ptr);

if(ptr == 0){

menu();

}

else if(ptr == 1){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Top time");

lcd.setCursor(0, 1);

lcd.print(timeValue); // RECALL NUMBER!!! TOP TIME

lcd.setCursor(13,1);

lcd.print("min");

ptr = 5;

}

else if(ptr == 2){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Total distance");

lcd.setCursor(0, 1);

lcd.print(distanceValue); // RECALL NUMBER!!! TOTAL DISTANCE

lcd.setCursor(14,1);

lcd.print("mi");

ptr = 6;

}

else if(ptr == 3){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Total energy");

lcd.setCursor(0, 1);

lcd.print(powerValue); // RECALL NUMBER!!! TOTAL WATTHOURS

lcd.setCursor(15,1);

lcd.print("J");

ptr = 7;

}

else if(ptr == 4){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Scroll down to ");

lcd.setCursor(0, 1);

lcd.print("read more!!! (V)"); // RECALL NUMBER!!! TOTAL WATTHOURS

ptr = 8;

}

}

void scrollDown(int i){

Serial.println(i);

if (i == 1){

lcd.setCursor(0, 1);

lcd.print("Total distance ");

ptr = 2;

}

else if (i == 2){

lcd.setCursor(0, 1);

lcd.print("Total energy ");

ptr = 3;

}

else if (i == 3){

lcd.setCursor(0, 1);

lcd.print("About! ");

ptr = 4;

}

else if (i == 8){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Electronics bike");

lcd.setCursor(0, 1);

lcd.print("worked on by: ");

ptr = 9;

}

else if (i == 9){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("A. McKay '13");

lcd.setCursor(0, 1);

lcd.print("J. Wong '15");

ptr = 10;

}

else if (i == 10){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("A.Karapetrova'15");

lcd.setCursor(0, 1);

lcd.print("S. Walecka '15");

ptr = 11;

}

else if (i == 11){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("S. Li '17");

lcd.setCursor(0, 1);

lcd.print("N. Sandford '17");

ptr = 12;

}

else if (i == 12){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("For His Majesty ");

lcd.setCursor(0, 1);

lcd.print("Dwight Whitaker ");

ptr = 13;

}

else if (i == 13){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Phys 128 ");

lcd.setCursor(0, 1);

lcd.print("Pomona College ");

ptr = 14;

}

else if (i == 14){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Paid for by the ");

lcd.setCursor(0, 1);

lcd.print("SIO and Dept of ");

ptr = 15;

}

else if (i == 15){

lcd.clear();

lcd.setCursor(0, 0);

lcd.print("Physics and ");

lcd.setCursor(0, 1);

lcd.print("Astronomy. ");

ptr = 16;

}

}

void scrollUp(int i){

if (i ==2){

menu();

}

if (i>2){

scrollDown(i-2);

}

}

 

 

Шаг 9: Общая схема и код

 

kak-sobrat-velo-generator28

kak-sobrat-velo-generator29

95% нашей цепи собрано на монтажной плате, а датчики и другие электронные компоненты подключены через штырьковые разъемы, что очень удобно. Полный код прикреплен файлом megabiker1или выложен здесь, для тех, кто имеет Arduino IDE. Признаю, код можно написать получше, но и на таком мозгоподелка великолепно работает.

 

 

 

Шаг 10: Финишная доработка

 

kak-sobrat-velo-generator30

kak-sobrat-velo-generator31

kak-sobrat-velo-generator32

kak-sobrat-velo-generator33
Окончательным шагом мозгопроектом является «окультуривание» поделки, то есть придание ей завершенного вида.

Просто аккуратно собираем провода в жгуты и скрываем их в коробе в передней части стенда. Провода, идущие к задней части, скрываем половинкой ПВХ-трубы, которую затем крепим к основанию. Аккумулятор также скрываем – помещаем в коробку, на руль монтируем пластиковый стенд для книги или телефона, на него же крепим ЖК-дисплей. Тумблер из Шага 2, который защищает от фантомных нагрузок, изолируем и крепим на ручке руля.

И в качестве финального аккорда, окрашиваем самоделку в любой выбранный цвет (не закрашивая,  конечно, электронику и движущиеся элементы).

Идеи для улучшения поделки:
• Радиатор для контроллера заряда
• Защита от воздействий окружающей среды (чтобы использовать самоделку и на улице)
• Установка датчика Холла для считывания оборотов колеса
• Более функциональный стенд для книг, держатель чашки
• Расширенное и более удобное меню
• Более продвинутый код

Итак, мозго-вело-генератор готов, надеюсь было полезно!

Удачи в творчестве!

 

( Специально для МозгоЧинов #Bike-Generator-Charging-Station

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]


Вверх