Приветствую, мозгочины! Самоделка данного мозгоруководства имеет великолепное свойство - она позволяет совместить приятное с полезным, а именно, занимаясь спортом еще и генерировать электричество.
Основа самоделки – велосипед сопряженный с двигателем, который и будет переводить ваши калории в электрический ток. А если подробнее, то вращение педалей передается на заднее колесо, которое соответственно вращает вал двигателя, вследствие этого в обмотках двигателя возникает электрический ток, который через контроллер заряда поступает на подключенный аккумулятор и «консервируется» там. К аккумулятору подключен инвертор, имеющий два выхода-розетки и два USB-выхода. Для управления и контроля всей электроники используется микроконтроллер Arduino, включающий/отключающий контроллер заряда и инвертор, а также отображающий посредством ЖК-дисплея параметры с датчиков.
Материалы и компоненты:
• Велосипедная рама с задним колесом
• Пиломатериалы и болты (для подставки)
• Велосипедный стенд для тренировок
• Мотор 24В
• Ремень от системы охлаждения
• Шкив для ремня
• Аккумулятор 12В
• Зарядное устройство DC-DC
• Инвертор DC-AC с USB-выходами и розетками
• Arduino (я использовал Leonardo, но и другие сгодятся)
• МОП-транзистор ( полевой транзистор с изолированным затвором)
• Светодиод и фотодиод
• Датчик с эффектом Холла
• ЖК-экран
• Тумблер «On/Off»
• Реле, регулятор напряжения 5В, диод, кнопки и резисторы
Шаг 1: Подставка
Для начала сооружаем подставку передней вилки из куска фанеры 60х180см, брусков 5х10см и шпильки с гайками. Я сделал ее потому, что велосипед мне достался без переднего колеса и пришлось придумывать как его зафиксировать. Подставка поделки получилась функциональная и выдерживает напор даже самых рьяных «гонщиков».
Для заднего колеса тоже можно сделать какую-либо стойку, но я пришел к выводу, что велосипедный стенд наиболее подходящий вариант. Просто нужно снять дополнительную нагрузку на колесо, какая иногда бывает на этих стендах, так как для генерации она только помешает.
В качестве генератора можно взять 24-х вольтовый мотор от мотороллера, который заставим не «кушать» электричество, а вырабатывать его. С обода заднего колеса снимаем покрышку с камерой и надеваем ремень от системы охлаждения, от ее же берем шкив, который соответственно устанавливаем на вал мотора. После того надеваем ремень на шкив и натягиваем его, затем закрепляем мотор в данном положении на фанерном основании.
Конструкция стенда такова, что имеет возможность подстройки, и данная опция позволяет натягивать ремень, а также вынимать велосипед при необходимости.
Шаг 2: От генератора к аккумулятору
В качестве «накопителя» можно использовать почти любую аккумуляторную батарею, я к примеру, взял 12В свинцово-кислотный аккумулятор, потому что он был под рукой. Но в любом случае нужно знать технические характеристики и условия эксплуатации выбранного аккумулятора для правильного заряда/разряда, которые можно узнать из тех.паспорта. В моем случае аккумулятор не «любит» когда напряжение повышается больше 14В, и силу тока не выше 5.4А .
Полный разряд, а также перегрузка аккумулятора может повредить его или снизить срок службы, поэтому в мозгоцепь установлен тумблер «On/Off» который предотвращает утечки тока под фантомными нагрузками, а еще установлен микроконтроллер Arduino, отображающий состояние цепи.
Естественно, что нельзя напрямую подключить аккумулятор к клеммам мотора, это попросту «убьет» аккумулятор, поэтому между ними устанавливаем контроллер заряда, который будет подавать на аккумулятор электричество тех силы тока и напряжения, которые ему требуются. Сам контроллер будет включаться при начале кручения педалей самоделки, а 3-х секундное удержание кнопки пуска контроллера проверит состояние аккумулятора, и если ему требуется зарядка, то она начнется. При остановке кручения педалей контроллер выключается.
При покупке контроллера заряда главное подобрать нужные характеристики, то есть, чтобы он работал в тех же диапазонах, что и генератор с аккумулятором. Так для моей мозгоподелки нужен контроллер, который может принимать входное напряжение до 24В и обеспечивать 14В с силой тока не более 5.4А. В основном контроллеры имеют возможность настройки параметров, поэтому я просто выставил на нем силу тока в 5А, как и требуется для моего мозгоаккумулятора.
Шаг 3: Инвертор
Просто подключить для зарядки свои гаджеты к аккумулятору нельзя, так как для этого требуются тоже определенные напряжение и сила тока, поэтому к аккумуляторы подключаем инвертор, выдающий через свои розетки и USB-выходы электричество с нужными для зарядки параметрами.
Инвертор для поделки следует покупать в соответствии с параметрами аккумулятора и рассчитанной мощностью. Так аккумулятор выдает 12В, мощность для зарядки телефона примерно 5Вт, а ноутбука 45-60Вт. Я подобрал инвертор с мощностью 400Вт, 2-мя розетками и 2-мя USB-выходами, хотя не планирую одновременно заряжать гаджетов на 400Вт.
Инвертор можно не устанавливать если вы планируете заряжать только телефон или другие USB-устройства. Тогда нужно лишь понизить напряжение от аккумулятора до 5В и «вывести» его через USB-шнур. При данном способе электричество лишний раз не преобразуется из постоянного в переменное, а затем из переменного в постоянное, но многие все же склонны доверять инвертору, чем импровизированному USB-порту.
Сам инвертор подключается просто: положительный вход инвертора к положительной клемме аккумулятора, отрицательный мозговход к отрицательной клемме. Да и работает все просто: мотор заряжает аккумулятор через контроллер заряда, аккумулятор «питает» инвертор, а тот заряжает подключенные гаджеты.
Шаг 4: Arduino и заряд батареи
Ранее уже было сказано, что для того чтобы началась зарядка аккумулятора нужно удерживать кнопку пуска контроллера заряда в течение 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 и инвертор
Держать постоянно подключенным инвертор к аккумулятору не выгодно по нескольким причинам. Во-первых, фантомная нагрузка разряжает мозгоаккумулятор, а во-вторых, нужно сделать «защиту» от хитрецов желающих подзарядить гаджет, но не желающих покрутить для этого педалей. Поэтому снова задействуем 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 и обратная информация
В качестве обратной связи во время тренировки можно взять значения частоты вращения заднего колеса, то есть «велосипедист» будет не только заряжать аккумулятор, но и получать информацию об интенсивности своей тренировки. Чтобы считать обороты заднего колеса можно использовать оптический датчик и датчик Холла.
Оптический датчик
В своей мозгоподелке я пошел путем установки оптического датчика для считывания числа оборотов заднего колеса, и сделал этот сенсор из попавшихся по руку деталей. Суть проста: к ободу колеса прикреплен непрозрачный объект, здесь тонкий крашеный пластик, который при вращении периодически прерывает луч светодиод-фотодиод. Сами фотодиод и светодиод установлены в куске пенопласта с выбранной полостью, в которой вращается колесо (см. фото). Из-за податливости пенопласта в нем легко разместить и настроить систему светодиод-фотодиод, а именно разместить их на одной линии, это важно, так как фотодиоды очень чувствительны к углу падающего луча. В итоге, пластик при вращении должен не мешать самому вращению обода, и прерывать луч.
Схема подключения диодов тоже проста: на оба диода подается от микроконтроллера 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 и датчик силы тока
Контроллер заряда нашей самоделки отображает силу тока идущей от аккумулятора, но можно использовать еще силу тока в качестве индикатора интенсивности тренировки. И для этих целей будем использовать эффект Холла упомянутого в предыдущем шаге, то есть пропуская ток от контроллера заряда через специальный датчик с эффектом Холла, который вырабатывает напряжение пропорциональное магнитному полю, создаваемое проходящим током, можно косвенно измерить силу тока идущего на батарею. Для обработки полученных значений, к сожалению, нет конкретных таблиц соотношений вырабатываемых напряжений и токов, но эту мозгозадачку можно решить пропусканием через датчик известных токов и замера вырабатываемого датчиком напряжения. По полученным таким образом данным и выводится соотношения напряжения и тока.
Этот ток может быть преобразован в другую статистику - энергии подаваемой на аккумулятор и общей выработанной энергии. То есть сравнивая энергию идущую на аккумулятор и энергию потребляемую для зарядки подключенных устройств, можно определить нужна ли зарядка аккумулятора, в случае если подключенные устройства расходуют боле энергии, чем может выдать аккумулятор.
Пример кода:
/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: ЖК-дисплей
Существует много вариантов вывода информации используя 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: Общая схема и код
95% нашей цепи собрано на монтажной плате, а датчики и другие электронные компоненты подключены через штырьковые разъемы, что очень удобно. Полный код прикреплен файлом megabiker1или выложен здесь, для тех, кто имеет Arduino IDE. Признаю, код можно написать получше, но и на таком мозгоподелка великолепно работает.
Шаг 10: Финишная доработка
Окончательным шагом мозгопроектом является «окультуривание» поделки, то есть придание ей завершенного вида.
Просто аккуратно собираем провода в жгуты и скрываем их в коробе в передней части стенда. Провода, идущие к задней части, скрываем половинкой ПВХ-трубы, которую затем крепим к основанию. Аккумулятор также скрываем – помещаем в коробку, на руль монтируем пластиковый стенд для книги или телефона, на него же крепим ЖК-дисплей. Тумблер из Шага 2, который защищает от фантомных нагрузок, изолируем и крепим на ручке руля.
И в качестве финального аккорда, окрашиваем самоделку в любой выбранный цвет (не закрашивая, конечно, электронику и движущиеся элементы).
Идеи для улучшения поделки:
• Радиатор для контроллера заряда
• Защита от воздействий окружающей среды (чтобы использовать самоделку и на улице)
• Установка датчика Холла для считывания оборотов колеса
• Более функциональный стенд для книг, держатель чашки
• Расширенное и более удобное меню
• Более продвинутый код
Итак, мозго-вело-генератор готов, надеюсь было полезно!
Удачи в творчестве!
( Специально для МозгоЧинов #Bike-Generator-Charging-Station