PDA

View Full Version : arducyclo



AmEv
08-01-2012, 04:29 PM
I've had the idea for a while now:

An Arduino-based bicycle control system. It would control blinkers, lights, and possibly a couple other things, such as a speedometer.

The bicycle itself is a blue K2 (I believe model 500), and it''s in need of a few minor repairs. Other than that, it currently works, and it hits ~30 like a charm.

The Arduino itself will be in a waterproof case. It will be velcroed underneath the seat, as that's a secure location for it. LEDs will be extensively used in this.


Pix to come :D

crenn
08-02-2012, 02:35 AM
Sounds like a good project and reasonably easy as well! If you need help, just post in the thread and I'll see what I can do!

TLHarrell
08-02-2012, 11:22 AM
If you want to go a little overkill with wiring, look into chasing everything inside the frame. If you wire up a much smaller AVR chip instead of a full blown Arduino board, you could easily fit it through a small hole. Rig up some supercaps to power everything, and charge the system from a small stepper motor mounted on the frame at the crank. Completely invisible would be awesome.

AmEv
08-02-2012, 02:25 PM
Naw, I want this to be easily upgradeable and replaceable.

I am planning on having it generator/rechargeable battery-run, though.

Not a bad idea, though. Zip ties and phone cord will suffice, though.

CorsePerVita
08-03-2012, 02:49 PM
Would be curious on the speedometer thing.

AmEv
08-03-2012, 03:14 PM
Well, I've got an old magnetic-style system that has no sensor. Got the magnet, receiver, and cables. Just not the sensor itself.

That's taken care of.


What I'd need help with is, interfacing it with the Arduino, and calibrating it for 26" tires.

TLHarrell
08-03-2012, 03:57 PM
This should get you on the way... equations available for calculating RPM to MPH. http://endless-sphere.com/forums/viewtopic.php?f=28&t=16114 Should be easy enough to put that into an Arduino. Count the "blips" as the wheel rotates on an input pin. Number per minute will give you RPM.

As far as a sensor, just find a simple reed switch. It'll close when the magnet passes it. In the case of a magnetic ring type sensor, it may trigger twice per revolution, so you'd have to test that and divide accordingly.

26-inch tire
1 mph = 12.93 rpm
1 kph = 8.10 rpm

10 mph (16 kph) = 129 rpm
11 (18 ) = 142
12 (19) = 155
13 (21) = 168
14 (23) = 181
15 (24) = 194
16 (26) = 207
17 (27) = 220
18 (29) = 233
19 (31) = 246
20 (32) = 259
21 (34) = 272
22 (35) = 285
23 (37) = 297
24 (39) = 310
25 (40) = 323
26 (42) = 336
27 (43) = 349
28 (45) = 362
29 (47) = 375
30 (48 ) = 388

AmEv
08-03-2012, 04:50 PM
It's a magnet-activated switch. Confirmed with a multimeter.

When the magnet hits the switch, there's a loop. No magnet, open circuit.

I was almost thinking counting the time between "on" states.

So, grabbing that info, inverting the formula, should give me the time in between "clicks" for speed.



*Oh, and the switch is already mounted on my bike.

AmEv
08-03-2012, 05:58 PM
OK, here's what I'm thinking:

The main three purposes of the Arduino is brakes, turn signal, and speedometer.

Brakes: I'm going to install switches inside the brake lever areas. When the switch is released, it turns the back red LEDs from medium-brightness to full-brights.


Turn signal: I think having an Arduino do the turn signal on the bike will be better, as the relay-capacitor styles will wear off after a while. Just a little delays.


Speedometer: This is where math comes in. Time between "ticks" will be directly related to the RPM, and thus, FPM, and thus, MPH. Probably going to just use a dual 7-digit LED display, powered by some sort of LED driver. Save ports on the 'duino.

Now, the tricky part is, figuring out how to lock the display and 'duino down to the bike.

TLHarrell
08-03-2012, 09:22 PM
Locking it down isn't a problem if you run most of the stuff inside the tubes. The battery/cap to run it from could be in the seat tube easily enough. Yeah, I know you don't want to do it that way, but it'd be more secure.

I was thinking a dual 7-segment display would be the way to go too. See if you can rewrap your handlebars so only the main part of the display sticks out. I suck at handlebar wrapping. Probably take it to a shop and have them do it. Bonus is that it'll cover your wiring too. You should be able to get a display from Sparkfun or somewhere similar that has a display capable of taking data by two-wire connection. Less pins.

For driving the LEDs, simply run them in series/parallel groups up to your operating voltage. Switch them with a transisitor from your Arduino pin.

For brakes, I'd figure a microswitch at the brake caliper itself would be easier to mount. Or you could put one along a cable where it runs along the frame. Bend the metal trigger into a ramp, and secure a split sinker (for fishing) or something similar along the cable so it pushes against the switch.

Needed pins: (not incl. ground)
Brakes (1)
Turn Signals (2)
Speedometer (2)
Brake Trigger (1) (multiple switches can be wires in series)
Turn Signal Buttons (2)

You need 8 signal pins. A full Arduino board is overkill. See if you can wire it on a smaller chip. Saves money, and is easier to stash on the bike.

Entirely up to you though... just tossing out ideas. If I were to do it, that'd be the way I'd go.

crenn
08-04-2012, 09:50 AM
To drive the 7-segment displays, I'd recommend either using transistors (there is a limit to the amount of current the ATMega can drive/sink) or another chip which will make driving it easier. Maybe look at an I2C port expander for driving the 7-segment displays. That way you can drive both with 2 pins. If you want a speedo, you either need to connect it to a timer for input capture or use external interrupts, you only need a single pin for this.
As TLHarrell mentions, for brakes, the best trigger is a micro switch, although you'd want them in parallel not series.
For the lights themselves, if you want to adjust brightness levels, you need PWM pins, there should be enough PWM pins for you to use for all 3 conditions (brakes, and turn signals). Just remember you need to program the arduino without delays.
Lastly, there is a trick you can use to use a single pin for the turn signal buttons, but it's not recommended and you most likely have enough pins, no sweat. You can set up a resistor divider and use the switches to 'short out' resistors and by measuring the voltage over a resistor, you can work out which switch is being pressed. However it's prone to noise, which is a factor.

AmEv
08-04-2012, 11:48 AM
I'll look at what parts I need to buy. I've got a lot on my plate right now, and this happens to just be near the top.

Crenn, you'll have to give me some pointers in teaching me Arduino code.

AmEv
08-05-2012, 07:41 PM
Time to break out Fritzing.

And this is what I have so far. Image will auto-update as I progress.

http://ubuntuone.com/7mR87cmmA1CEwPbb9QjJSI

crenn
08-05-2012, 09:03 PM
You're going to need some resistors for driving the transistors (unless they're mosfets, but it couldn't hurt to use them), also for the LEDs to limit the amount of current going to them. You also need another 2 transistors for the LEDs. One more for the turning signals and another for the brakes. As for resistor values and transistor values, this is going to depend on what you decide the system voltage will be. For example, if you're using a 6V powersupply, you'd want to use 2-3 LEDs in series (depending on forward voltage of the LEDs, you can measure this if you want!).

Now for the LED display, this is a little more difficult to do, however it's possible. You could drive each one independantly but that would tie up 14 pins immediately. I'd recommend tieing the segment signals both both together and being able to switch the common anode(positive)/cathode(negative) pins by attaching them to the microcontroller or using transistors (most likely the safer method for the microcontroller). The same could be said for the segment signals. You also will need a resistor for each segment.

Lastly, you're going to need a pulldown resistor for the magnetic switch to be able to measure it correctly. Why? When the switch isn't activated, it will be floating, if it's closed it be drawn to the high voltage. Although you could hook it up so the pullup resistor in the microcontroller is used (thus reducing the BoM) and when the switch is activated, it will draw the line to ground. That's probably a better method of doing it.
Is that Arduino Nano running at 3.3V or 5V? This is something to think about as it will effect your design/values.

Other things to consider, what rate should the turn signals flash at? How long should they flash or how are they deactivated? How will the headlights be turned on? If you're wanting to control the brightness of the LEDs, how will you set that? Will it be another button or will it be something you need to plug in a computer for?

Now the programming. I'd recommend creating a library to drive the display, you don't have to do anything fancy, but it will make it easier to interface in the future. As I mentioned before, you don't want to use delays. The reason I say this is that if you're wanting something to occur, you need to make it sure that it reacts within a certain time for the user (ie you) so that it's responding how you want it to do. I do this will almost all of my code. If I can avoid delays I will (there are times where avoiding delays makes things more difficult) however delays are sometimes needed. If you have a delay, nothing else can occur (unless you're using interrupts, and you'll need to use interrupts for this project) until that delay finishes.

Just letting you know, some good examples for working out speed of something spinning would be the fan controller code done for Oneslowz28 here:
http://www.thebestcasescenario.com/forum/showthread.php?t=23437
As for an example of code where things must happen without delays being used, check out this:
http://www.thebestcasescenario.com/forum/showthread.php?t=26767 (Can't remember if he released the code, did a little bit of searching but can't see it)

AmEv
08-05-2012, 09:40 PM
Thanks for the quick turnaround time, Crenn!

You're going to need some resistors for driving the transistors (unless they're mosfets, but it couldn't hurt to use them), also for the LEDs to limit the amount of current going to them. You also need another 2 transistors for the LEDs. One more for the turning signals and another for the brakes. As for resistor values and transistor values, this is going to depend on what you decide the system voltage will be. For example, if you're using a 6V powersupply, you'd want to use 2-3 LEDs in series (depending on forward voltage of the LEDs, you can measure this if you want!).
It wouldn't be that hard to wire 2 LEDs in series. That way, it would be brighter. Good thinking.
The main reason I did the 4 cells is because 4 AA rechargeable batteries=4*1.2V=4.8V. I can still put in a 5V regulator for the Arduino, though.

Now for the LED display, this is a little more difficult to do, however it's possible. You could drive each one independantly but that would tie up 14 pins immediately. I'd recommend tieing the segment signals both both together and being able to switch the common anode(positive)/cathode(negative) pins by attaching them to the microcontroller or using transistors (most likely the safer method for the microcontroller). The same could be said for the segment signals. You also will need a resistor for each segment.
I've heard about the "4511" LED driver. Uses 4 pins. So, that should give me more room.


Lastly, you're going to need a pulldown resistor for the magnetic switch to be able to measure it correctly. Why? When the switch isn't activated, it will be floating, if it's closed it be drawn to the high voltage. Although you could hook it up so the pullup resistor in the microcontroller is used (thus reducing the BoM) and when the switch is activated, it will draw the line to ground. That's probably a better method of doing it.
Is that Arduino Nano running at 3.3V or 5V? This is something to think about as it will effect your design/values.
The speed sensor will go directly from the Arduino to the switch, to the common ground. Just set the pin as an input.

Other things to consider, what rate should the turn signals flash at? How long should they flash or how are they deactivated? How will the headlights be turned on? If you're wanting to control the brightness of the LEDs, how will you set that? Will it be another button or will it be something you need to plug in a computer for?
Now my brain's really chugging along. Thanks for the mental exercise (no, seriously, I needed it!)
I'm currently thinking about on for 1/2 second, off for 1/2 second.

Now the programming. I'd recommend creating a library to drive the display, you don't have to do anything fancy, but it will make it easier to interface in the future. As I mentioned before, you don't want to use delays. The reason I say this is that if you're wanting something to occur, you need to make it sure that it reacts within a certain time for the user (ie you) so that it's responding how you want it to do. I do this will almost all of my code. If I can avoid delays I will (there are times where avoiding delays makes things more difficult) however delays are sometimes needed. If you have a delay, nothing else can occur (unless you're using interrupts, and you'll need to use interrupts for this project) until that delay finishes.

Well, my current programming skills:

HTML: Fairly confident, can write and manage own code.
JS: Taught as same time as HTML, but was emphasized more than HTML, so very confident.
C++: Know my way around (somewhat), able to fix some existing code (incorrect #include directives, mainly), but don't even know enough to write own code.
Java: Barely know. Barely played around with Java.
Arduino: Same as Java.


What I'm nervous about, though, is that when the blinkers are activated, the speedometer locks up. From what I've heard, processors can only understand one line of code at a time.

TLHarrell
08-05-2012, 10:20 PM
How about since the left and right signals are not very far apart, you pulse them in order to show direction? For left, you'll do right, short delay, left, longer delay. For right it's left, short delay, right, longer delay. Unless you form an obvious arrow, direction is fairly difficult to see when both sets of LEDs are close to the centerline of the bicycle.

AmEv
08-05-2012, 10:34 PM
Well, on the handlebars, it'll be easy to spot there.


I can reserve the brakes for the seat.

crenn
08-06-2012, 08:54 AM
Thanks for the quick turnaround time, Crenn!

It wouldn't be that hard to wire 2 LEDs in series. That way, it would be brighter. Good thinking.
The main reason I did the 4 cells is because 4 AA rechargeable batteries=4*1.2V=4.8V. I can still put in a 5V regulator for the Arduino, though.

I've heard about the "4511" LED driver. Uses 4 pins. So, that should give me more room.

It's not a case of the LEDs would be brighter (brighter is a product of the current flowing through it) but more LEDs would have the accumulative impact of the array appearing brighter.
The ATMega will run happily down to 4.5V at 16MHz, if it goes lower, you do need to run it at 8MHz. I would actually just use a 3.3V arduino for this project if you can manage it. Just a note for the 5V regulator (I'm assuming a 5V linear regulator), you need to have a certain voltage over the target voltage. With the popular LM7805 regulator, you need about 6V to output 5V. Arduinos will generally have a 5V regulator onboard, so this shouldn't be an issue. Look into LDOs (Low Drop Out) if you need something better.

I looked up the 4511 LED driver and it's going to make things much easier for you. I'd recommend using it as it will reduce the pins you need to interface with the LED displays from potentially 14 down to 6. 4 pins will be used to give both chips a binary number and a pin for each chip to get the number to be 'latched'. I knew there was a driver for those modules, but didn't know the model number. Even I learn new things!


The speed sensor will go directly from the Arduino to the switch, to the common ground. Just set the pin as an input.

An input is floating unless it has a something to drive that pin. Usually this is an external device such as an output from an RC receiver. The method you describe will cause issues with the switch isn't activated(pin will be floating), however using the internal pull-up will solve it.


Well, my current programming skills:

HTML: Fairly confident, can write and manage own code.
JS: Taught as same time as HTML, but was emphasized more than HTML, so very confident.
C++: Know my way around (somewhat), able to fix some existing code (incorrect #include directives, mainly), but don't even know enough to write own code.
Java: Barely know. Barely played around with Java.
Arduino: Same as Java.

Arduino is just a set of C++ libraries (poorly written, but not going into that) so it's not very hard to do things if you know a bit of C++. C++ is not a hard language to learn, however some of the concepts are not easy to understand. It's also a flexible language, which is good news. You're not going to have too much of a problem getting it working, the libraries and concept of wiring/arduino is to make it easy for anyone to pick it up and work with microcontrollers. As for making a library, I can help you with that, you'd be amazed how easy it is to write one!
I don't know Java either! If you had said you knew PHP, that would have been good as PHP is some ways similar to C++.


What I'm nervous about, though, is that when the blinkers are activated, the speedometer locks up. From what I've heard, processors can only understand one line of code at a time.

Processors can only do one instruction at a time, however you need to think of how many instructions it can do. An Arduino running at 16MHz can roughly do 1 instruction per cycle (Hz) which means it will do 16 million instructions a second. This is a generalisation, as some instructions will need longer than a single cycle, but that isn't something you really need to worry about. If you're curious about this stuff, I'd look into assembly, as that is using instructions directly to make your program, however it's not exactly as straight forward as writing code in C/C++.
Anyway, what I'm saying is that this shouldn't be a problem for your application as the data is processed quickly and the range of things you want your microcontroller to do is limited and not very processor intensive. If you want to know how powerful these ATMegas are, think of the quad copters you see around now, those things have to crunch numbers like no tomorrow to be stable enough to fly, but they manage it! Your application is a walk in the park figuratively.
If you program it right, your blinkers will not lock up, your speedo won't freeze and the earth won't stop turning. The trick with microcontrollers is you make it so things are driven by events and expect things to run one after the other in periods (schedule timing essentially). In your case, you look at the time since the microcontroller turned on and hey presto! You can blink an LED without ever using a delay, which means you can do other things as well without it appearing that the LED never stops blinking. Also you can use interrupts so that your code is happily running and then it stops (if the interrupt is triggered) and runs a bit of different code then switches back to where it was. Don't worry too much about it, I wouldn't be ;D

AmEv
08-06-2012, 01:09 PM
Well, it looks like the Mini, rather than the Nano, will be better for me. So there's that.
For serial (and beta-testing), I can just temporarily hijack the floppy project board.

And no, I really don't know PHP, either. I brushed on some concepts during the JS class, though.



We need to Google Talk sometime. When you're ready, I'll PM my Talk address to you.

AmEv
08-06-2012, 04:41 PM
I think I'm getting it.


Lemme write some pseudo-code when I get the time.

*Here: http://ubuntuone.com/5XM32PKk70Ak9lxrzq4acS
It's a combination of code and pseudo-code. From what I learned of JS. Somewhat....

crenn
08-10-2012, 10:59 PM
Sorry I haven't replied in some time, just been busy with my first week of uni and getting back into my job. Also been getting new stuff of late so that's part of the reason, but anyway, let's take a look.

I did go through your code the other day and with minimal work it would work fine with the Arduino, no issues. There are a few things that need working such as doing the maths for the speedo (we'll go into that) and also how your blinking is done.
In the pseudo code, there isn't actually anything getting the time from the microcontroller to be able to process the blinking. There is a function defined in the Arduino library called millis() which can help with this, it returns a unsigned long value which represents the number of milli seconds since the microcontroller was turned on. In your main code, look at doing something like this:

if ((millis() - blinkertime) > 500) {
byte buttonstate = (digitalRead(buttonLeft) | (digitalRead(buttonRight) << 1) );
blinker(buttonstate);
blinkertime = millis();
}

This way in your blinker function, you don't have to worry about timing, only what LEDs are flashing, and this could be done just by toggling the pin states. (Or remember what you wrote to the pins last)

I don't use google talk much but I can, you can PM me your talk address to me whenever you feel like you want to.