Introduction: Minimalist Bicycle Indicator, Touch-Enabled!

Hi there! This is my first Instructable. I always wanted to make things from scratch just to see how it works and who doesn't like DIY (Do it yourself) stuff when you can modify something according to your needs right? Well as interesting as a DIY might sound, it takes a bit of effort to make it happen. Looking through the Instructables website is a great way to start your DIY aspirations and that's how I started building some of my projects earlier, but I never thought I would be making one.

Just as the opportunity has come my way, I have made a Bicycle Indicator with a minimalist design and touch-enabled. I know there are many Instructables or online sources for a bicycle indicator but most of them either took some more space or weren't smart enough to modify them in a particular way. If you are looking for an indicator that is smart enough to fulfill your needs and giving you a chance to modify them as per your needs, then this Instructable is for you!

Why bicycle Indicator?

I love cycling around the city! I take my cycle and just go for a ride either in the mornings or evenings. Sometimes, at night, it is difficult to ride, as the traffic behind you won't be able to notice you and that's a dangerous sign. That is why I wanted to build an Indicator myself with all the materials I had with me at home and also It looks great on the bicycle as you ride in the city turning the indicators ON!

Making a project without having to face any problems, doesn't happen! But I will tell you all the mistakes I made, while building this, as a "Handy Tip" so that you don't try to make them. The YouTube video contains an Illustration of how the project is built, small animations to convey how things work, and how the indicator looks on the road! Most elaborate information is given in this Instructable. As you proceed I will be tagging the segments of my youtube video as "Timeline: " at each step for you to look at how things work practically. You can get more information by clicking the highlighted links provided.

Features of this project:

  • Right Turn Indication
  • Left Turn Indication
  • Night Sight Indication
  • Touch-Enabled

Step 1: Materials to Get Started

Always keep extra quantity as to what is mentioned above. I have linked the components on Amazon and some best buy kit for soldering materials!

Timeline: Gather Materials

Step 2: Testing Components

Let's put your components to the test! This is really helpful to separate the components which are damaged or acting weird for some reason and also this phase lets you get the initial Hands-on experience with the components and do a bit of learning before going onto building the whole project.

Test for the type of RGB LED

There are two types of RGB LEDs we find the market. The common cathode type and the common anode type.

This is a handy tip (though larger) because I connected the LEDs as seen from this video here and the LED didn't light up as expected even after cross-checking the circuit several times. Then I realized that there are two types of this LED and going through the datasheet I finally got a solution! The problem with my circuit was the common cathode pin was connected to 3.3V as mentioned and I had kept by GPIO pin to HIGH so both the common cathode pin and the other 3 pins were at the same potential.

Solution:I connected the common cathode pin to the ground and the LED lit up! The reason I didn't change my code to keep the GPIO pins LOW because we will be using more LEDs later and the RPi gives us just two pins at 3.3 V which we need it for other purposes as well!

How to test for the type?

Keep the multimeter in continuity mode.
Tap the longest lead with the red tip of the multimeter and with the black tip, tap any one of the other leads.
If the LED lights up by performing the above step, it is a Common Anode RGB LED.
If it doesn't, reverse the multimeter tip now. Tap the longest lead with a black tip and red tip with any other leads.
Now it will light up showing that the LED is a Common Cathode RGB LED.

Handy Tip: I have used the Common Cathode Type in this project. Try to get these types only but even if the other type is available don't worry. The circuit connections remain the same, the only difference has to be made in the code which I will be giving as a comment next to the actual code line where you have to change. Take a breath.

Timeline:Test RGB

Reference: How to test RGB

RGB LED lights up!

To do this, check out the connection diagram given in the pictures above and connect as per the pins through a breadboard (to keep it safe to start with).

RED: Pin 11 (330-ohm resistor)

GREEN: Pin 13 (120-ohm resistor)

BLUE: Pin 15 (120-ohm resistor)

The resistor values vary due to the varying forward voltages of the leads.

Once you have connected them correctly, code the RPi in its inbuilt python IDE.

import RPi.GPIO as GPIO

#The pin numbers correspond to exact number on the RPi GPIO

Red_pin = 11
Green_pin = 13
Blue_pin = 15

#Connect Common cathode pin to Pin 6

def turnOn(pin):
    GPIO.setmode(GPIO.BOARD) 

    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, GPIO.HIGH) #GPIO.output(pin, GPIO.LOW) for common anode type

def turnOff(pin):
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(pin, GPIO.OUT)
    GPIO.output(pin, GPIO.LOW) #GPIO.output(pin, GPIO.HIGH)

def redOn():
    turnOn(Red_pin)

def redOff():
    turnOff(Red_pin)

def greenOn():
    turnOn(Green_pin)

def greenOff():
    turnOff(Green_pin)

def blueOn():
    turnOn(Blue_pin)

def blueOff():
    turnOff(Blue_pin)

try:
    while True:
        cmd = input("Type your command: ")

	if cmd == "red on": #type input commands as mentioned exactly inside ""
            redOn()
        elif cmd == "red off":
            redOff()
        elif cmd == "green on":
            greenOn()
        elif cmd == "green off":
            greenOff()
        elif cmd == "blue on":
            blueOn()
        elif cmd == "blue off":
            blueOff()
        else:
            print("Not a valid command")

except KeyboardInterrupt:
    GPIO.cleanup()

I referred to this Instructable, do check this out for detailed description and the code!

Using the same code above you can check for multiple LEDs together by connecting them in parallel on the breadboard and take out the single point from any of the pins connected together. Use different resistor values for each pin to check the brightness of your LEDs

Handy Tip: Make sure you connect the same pin-type parallel. That is, the red pin of one LED connects to the red pin of the other LED only.

Timeline: Make them glow!

TouchPad testing

The circuit connection is as shown here (Timeline). Connect them as shown and test your touchpads using the following code.

Code:

import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode(IO.BOARD)

touchpad1 = 11 #pin 11
touchpad2 = 13 #pin 13 

GPIO.setup(touchpad1, GPIO.IN)
GPIO.setup(touchpad2, GPIO.IN)

# We can club both the above statements together as
# GPIO.setup([touchpad1, touchpad2], GPIO.IN)

try:
    while True:
        if(GPIO.input(touchpad1) == True):
            print ("Touchpad 1 touched")
            sleep(2)
        elif (GPIO.input(touchpad2) == True):
            print ("Touchpad 2 touched")
            sleep(2)
        else:
            print("Not Touched")

except KeyboardInterrupt:
    GPIO.cleanup() #CTRL-C to exit

Testing an LED

Refer to this awesome instructable for testing your LED!

Once you have tested all the above components you are ready to build the bigger version of it.


Step 3: Soldering the Indicator Panel

If you are new to soldering check out this tutorial to learn some basics of it here (How to solder). If you are a pro at soldering, let us get started!

The Indicator Panel

You can find the Illustration of how to solder them on the perf board inthe images above.

We use 13 RGB LEDs for the panel. Separate them into three sections: left, right, and center to solder accordingly.

Important: Spacing of the LEDs

I have left 3 rows between the LEDs. As shown in the second picture.
This is important for the LED panel to look and feel good. We don't want the LEDs too far to increase the space or too near to not be able to distinguish the light from far away.

Handy Tip: Start by soldering all the Common Cathode Pins first

Handy Tip: Use Multi-Strand Wires for connecting the LEDs together as they are less sturdy and easy to bend. You can use the extra cut-off pins from the LEDs to connect the shorter distances

Right Section: (5 LEDs)

  • Connect all the Red Pins together
  • Connect all the Green Pins together
  • Connect all the Common Cathode Pins together

Left Section: (5 LEDs)

  • Connect all the Red Pins together
  • Connect all the Green Pins together
  • Connect all the Common Cathode Pins together

Center Section: (3 LEDs)

Handy Tip: This section requires enough caution. Don't solder all the pins together as we did in the above two sections!

  • Connect all the Red Pins together
  • Connect only the top and bottom LED's, Green Pin.
  • Connect all the Common Cathode Pins together

Wires

We need longer wires to connect the panel to the GPIO board.

Handy Tip:

  • Use Single-strand wires! They are sturdy enough to withstand mechanical stresses applied to it!
  • Keep the wires a bit longer than the actual length needed between the panel and the RPi (this is very handy while managing the wires later! (Timeline: Measurements)
  • Insulate after soldering! Very Important

Use a jumper wire and a single strand wire to solder. The jumper wire's one end has to be a female connector.
Solder them as shown here (Timeline)

Color code the wires as Red, Green, and Black. which corresponds to Red pin, Green pin, and Common cathode pin respectively.

We require 3 Black wires, 3 Red Wires, and 3 Green Wires.

Once the wires are ready. Solder the wires to the indicator LEDs.

Handy Tips:

  • Make sure the LEDs are soldered as per the connections given.
  • Make sure you have soldered the correct resistor values in place. If the values are changed, it will affect the brightness of the LEDs
  • One way to make sure all your LEDs are working is by using the multimeter meter given in Step 2. This is very handy as you will know if there is any short circuit the LEDs won't light up.
  • Don't strip off the ends of the wires longer than required. This will be difficult to keep them in place and also a higher risk of a short circuit.
  • Use multi-strand wire for connection between LEDs.
  • Use single-strand wire for connecting the sections to RPi.

Step 4: Put the Indicator Panel to the Test

Kudos! If you have soldered the panel correctly. Let's proceed with coding the Indicator now!

As mentioned earlier we will indicate a right turn, left turn, and turn on/off the night sight.

Refer to the connection of the circuit in Step 3.

Connect the wires of the panel as mentioned below:

  • Red Right -- Pin 7
  • Green Right -- Pin 11
  • Common Cathode Right -- Pin 6 (GND)
  • Red left -- Pin 13
  • Green left -- Pin 15
  • Common Cathode Left -- Pin 9 (GND)
  • Center Red -- Pin 16
  • Center Green( top and bottom ) -- Pin 18
  • Center Common Cathode -- Pin 14 (GND)

Test Code:

import RPi.GPIO as GPIO
from time import sleep

#Connect according to below pin numbers
Red_right = 7
Green_right = 11
Red_left = 13
Green_left = 15
Red_center = 16
Green_top_bottom = 18


GPIO.setmode(GPIO.BOARD)

def right_turn():

    print ("Turning Right")
    blink(Green_right, Green_top_bottom, 0)

def left_turn():

    print ("Turning Left")
    blink(Green_left, Green_top_bottom, 0)


def blink(pin1, pin2, pin3):

    if(pin3 == 0):

        GPIO.setup([pin1, pin2], GPIO.OUT)

        for x in range(10):

            GPIO.output([pin1, pin2], GPIO.HIGH)
            sleep(0.5)

            GPIO.output([pin1, pin2], GPIO.LOW)
            sleep(0.5)

    else:

        GPIO.setup([pin1,pin2, pin3], GPIO.OUT)

        for x in range(10):
            GPIO.output([pin1, pin2, pin3], GPIO.HIGH)
            sleep(0.5)

            GPIO.output([pin1, pin2, pin3], GPIO.LOW)
            sleep(0.5)

def night_sight():
    print("Night Sight ON")
    blink(Red_left, Red_right, Red_center)


try:
    while True:

        cmd = input("Test LED for: ")

        if cmd == "right turn":
            right_turn()

        elif cmd == "left turn":
            left_turn()

        elif cmd == "night sight":
            night_sight()

        else:
            print("Invalid Command")

except KeyboardInterrupt:
    GPIO.cleanup()

If your panel clears all the test phases as in the code, Well Done! Get ready for the next step.

If the panel doesn't light up, make sure you have followed all the steps correctly and looked through the handy tips before. If the problem still persists you can comment down below, I'll be ready to help.

Timeline: Test ONE (Check the video for the working prototype)

Step 5: Integrating the Indicator Panel With the Touchpad

Connecting it to the RPi

Make the connections as shown in the picture above.

Right Panel

Touchpad:

  • GND pin -- Pin 34
  • VCC pin -- Pin 1
  • SIG pin -- Pin 29

LED:

  • Anode(+) pin -- Pin 33

Left Panel

Touchpad:

  • GND pin -- Pin 30
  • VCC pin -- Pin 17
  • SIG pin -- Pin 31

LED:

  • Anode(+) pin -- Pin 35

Common GND: Pin 39 (For both the cathode of the LEDs) - Common Ground Soldering (Timeline)

Test Code:

import RPi.GPIO as GPIO
from time import sleep

Red_right = 7
Green_right = 11
Red_left = 13
Green_left = 15
Red_center = 16
Green_top_bottom = 18
right_touch = 29
left_touch = 31
right_led = 33
left_led = 35

triggered = 0

GPIO.setmode(GPIO.BOARD)
GPIO.setup([right_led, left_led], GPIO.OUT)

GPIO.setup(right_touch, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(left_touch, GPIO.IN, pull_up_down = GPIO.PUD_UP)

def right_turn(channel):

    GPIO.output(right_led, GPIO.HIGH)
    global triggered
    triggered = 1
    print ("Turning Right")
    blink(Green_right, Green_top_bottom)

def left_turn(channel):

    GPIO.output(left_led, GPIO.HIGH)
    global triggered
    triggered = 1
    print ("Turning Left")
    blink(Green_left, Green_top_bottom)

GPIO.add_event_detect(right_touch, GPIO.FALLING, callback = right_turn, bouncetime = 500)
GPIO.add_event_detect(left_touch, GPIO.FALLING, callback = left_turn, bouncetime = 500)

def blink(pin1, pin2):

    GPIO.setup([pin1, pin2], GPIO.OUT)

    for x in range(10):

        GPIO.output([pin1, pin2], GPIO.HIGH)
        sleep(0.5)

        GPIO.output([pin1, pin2], GPIO.LOW)
        sleep(0.5)

    GPIO.output([right_led, left_led], GPIO.LOW)
    global triggered
    triggered = 0

def night_sight():

    while (True):

        GPIO.setup([Red_center, Red_left, Red_right],GPIO.OUT)

        global triggered

        if (triggered == 0):

            print ("Night Sight ON")

            GPIO.output([Red_center, Red_left, Red_right], GPIO.HIGH)
            sleep(0.27)

            GPIO.output([Red_center, Red_left, Red_right], GPIO.LOW)
            sleep(0.27)

        else:

            print ("Night Sight OFF")
            GPIO.output([Red_center, Red_left, Red_right], GPIO.LOW)

try:
    night_sight()


except KeyboardInterrupt:
    GPIO.cleanup()

Touch the touchpad to see your light glow!

Timeline (without Indication LED): Test Two

Timeline (with Indication LED):Test 3

Code explanation: We want the night-sight to be running continuously and when we touch the touchpad it should stop and execute the function of the touchpad. To do this simultaneously we use something known as "Interrupts" in python. This allows us to run our normal code which is the night-sight here and also it triggers an event when a touch is detected. We use triggered variable as a flag to stop the night sight.

For more information on Interrupts, check this link.

Solder the Panel

Now let's solder the touchpad panels which will go to the handlebar of the bicycle. Refer to the connections as given in the picture above.

Now that you have tested your LED and the touchpad, you are good to go. If you haven't tested already please refer to this Step and the previous Steps.

Place the touchpad near to the handlebar as shown in the video. That is, for the right touchpad the touchpad is on the right and left to its left. Similarly, for the left touchpad, the led is on the right and the touchpad on the left which makes it easier for the thumb to reach.

PS: I haven't soldered the touchpad to the perf board because I was to reuse it again. Hence I just put it on the panel with double-sided tape.

Connect the panel to RPi using longer wires!

Step 6: Make It Smart!

Yes! Now that we have all our essentials of the Indicator up and running. Let's take it a step further to make it smart.

Here smart defines saving up on the battery as well. As you may have noticed the night sight is always turned on and sometimes this might not be required on a bright sunny day.
To overcome this problem lets integrate an LDR (Light Dependent Resistor) to give us the data of light intensity which we can collect and process our indicator accordingly.

Testing the LDR

I referred to this website for testing the LDR to check the light intensity and what value it returns.

Refer to the website tagged above for the circuit and the sample code for the working of the LDR.

Integrating the LDR to our code

Solder the LDR to the right panel of the touchpad as shown in the connection diagram above.

After soldering the pins in the right place its time for the last bit of the coding. The final code!

  • Connect the common point of the Cathode(-) of the capacitor and the LDR to Pin 36 on the RPi
  • The anode of the capacitor is connected to the Common Ground point referred to in Step 5

Final Code:

import RPi.GPIO as GPIO
from time import sleep

Red_right = 7
Green_right = 11
Red_left = 13
Green_left = 15
Red_center = 16
Green_top_bottom = 18
right_touch = 29
left_touch = 31
right_led = 33
left_led = 35

ldr = 36

triggered = 0

GPIO.setmode(GPIO.BOARD)
GPIO.setup([right_led, left_led], GPIO.OUT)

GPIO.setup(right_touch, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(left_touch, GPIO.IN, pull_up_down = GPIO.PUD_UP)

def right_turn(channel):

    GPIO.output(right_led, GPIO.HIGH)
    global triggered
    triggered = 1
    print ("Turning Right")
    blink(Green_right, Green_top_bottom)

def left_turn(channel):

    GPIO.output(left_led, GPIO.HIGH)
    global triggered
    triggered = 1
    print ("Turning Left")
    blink(Green_left, Green_top_bottom)

GPIO.add_event_detect(right_touch, GPIO.FALLING, callback = right_turn, bouncetime = 500)
GPIO.add_event_detect(left_touch, GPIO.FALLING, callback = left_turn, bouncetime = 500)


def light_sensing(ldr):
    count = 0

    #Output on the pin for
    GPIO.setup(ldr, GPIO.OUT)
    GPIO.output(ldr, GPIO.LOW)
    sleep(0.1)

    #Change the pin back to input
    GPIO.setup(ldr, GPIO.IN)

    #Count until the pin goes high
    while (GPIO.input(ldr) == GPIO.LOW):
        count += 1

    return count


def blink(pin1, pin2):

    GPIO.setup([pin1, pin2], GPIO.OUT)

    for x in range(10):

        GPIO.output([pin1, pin2], GPIO.HIGH)
        sleep(0.5)

        GPIO.output([pin1, pin2], GPIO.LOW)
        sleep(0.5)

    GPIO.output([right_led, left_led], GPIO.LOW)
    global triggered
    triggered = 0

def night_sight():

    while (True):

        GPIO.setup([Red_center, Red_left, Red_right],GPIO.OUT)

        global triggered

        if(light_sensing(ldr) > 7800):

            if (triggered == 0):

                print ("Night Sight ON")

                GPIO.output([Red_center, Red_left, Red_right], GPIO.HIGH)
                sleep(0.27)

                GPIO.output([Red_center, Red_left, Red_right], GPIO.LOW)
                sleep(0.27)

        else:

            print ("Night Sight OFF")
            GPIO.output([Red_center, Red_left, Red_right], GPIO.LOW)

try:
    night_sight()


except KeyboardInterrupt:
    GPIO.cleanup()

Voila! And the indicator is ready to roll.

Handy Tip: Before assembling the RPi and other components to the cycle make sure you test this program properly! Run it a few times to debug any errors.

Step 7: Painting and Assembly

Materials Required:

  • Wire Cutting/ Stripping Tools
  • One large storage box to fit in Raspberry Pi
  • One small storage box to fit the indicator panel
  • Paint
  • Paint Brushes

Start by painting the Indicator panel and the touchpad panels with black color. I used Acrylic Paints here you can use them of your choice which blends well with the perf board. Use a black background so as to make the LED panel vibrant and more standing out. Make the holes using a heated screwdriver or using any metal object to melt the plastic.

Note:Please be careful while making holes.

Timeline:Paint

Handy Tip: I used plastic boxes and the paint comes off easily. Make sure you use good quality paints

Once the Indicator and the panels are painted dry them out in the sun and get ready for assembling.

I have cut extra edges of the perf board in the Indicator Panel and the front panel to save space.

Check the video for assembly!

Timeline: Avengers! Assemble. (Assembling the indicator panel and RPi with boxes)

As seen in the video put the wires accordingly by making three holes in the larger box. One for RPi power bank wire, one for the touchpad panels, and one for the Indicator panel.
Only one hole is required for the smaller box.

Handy Tip: Check for the insulation of the wires and check if the wires are soldered properly before connecting them in the box.

Step 8: Remote Testing With VNC and Final Code

One final test before the indicator is fully ready. Connect your RPi to the VNC Viewer and run the program.

I always use a VNC server to run the program and debug any errors in the program. This way I can place the RPi directly to the place where I want to test without connecting the monitor externally.

Check this page to connect your RPi to VNC Server. (VNC Server)

Once you have connected the RPi to VNC Server. You can run the code on the virtual desktop and debug the errors.

Timeline:Run on Startup

Handy Tip: Once you have connected your Raspberry Pi to the virtual desktop you will sign in with the IP Address of the RPi. But if you get an error stating that the RPi refused the connection, it is because of the IP Address change in the RPI. This can happen when you restart your router or a WiFi hotspot and then try to login with the old address. The router assigns a new IP every time you restart it.
But if you remember the old IP Address of the RPi just increment the last digit by 1 and log in. Example: If the old IP address is 190.148.1.100 then log in using 190.148.1.101

Once you have checked if it is all working properly it time for the final assembly.

Always we can't have a virtual desktop to monitor or run the python script. So let us do that on startup.

We want our program to run once the RPi boots up. Check this website for more details on this!

If your RPi is on Auto-login setup, then continue;

Run the following commands in the terminal of the RPi

sudo nano /etc/profile

Scroll to the bottom and add the following line :

sudo python file_path &

The file_path here refers to the path of the python file where your final code is stored.

Note: The Ampersand (&) at the end of the file should be added so that your program runs parallel to the system boot. Because our program contains an endless loop, this step is mandatory so that even if the program isn't running as expected we can still use the RPi desktop to change the settings.

After this press CTRL-X and then Y
Press Enter twice and you will be back to the command terminal.

Reboot the Pi

Now the code should run on startup!

Step 9: Cable Management and Final Assembly

Congratulations! on finishing this project. I gave it the word Minimal as you have seen we have used fewer LEDs to show all the indications necessary and also with customized colors. Feel free to use different colors for your LEDs such as yellow for the turn indicators or any other.

If you have done this project click on "I made It" and share your experience. Do share your thoughts and also any suggestions or comments on this project. I would love to hear that!

Cable Management

Yes! As you might have noticed there are so many wires going in and around the cycles and managing them is hectic. I used cable tags, insulation tapes, and cable casing to hide the wires and also painted them black as you have seen the picture.

Handy Tip: Because you have left extra inches off your cables than required it is useful now to manage them properly without stressing them!
If one of your LEDs light up and others don't even if you have done everything right, the problem is in the Jumper Wires connected to the RPi, there will be a loose contact. If this persists use a male to female jumper wire to extend the wire and connect them. Use cable ties to keep the wires in place so that it won't move.

Now the Indicator is all set for a Ride! Enjoy it!

PS: In a further instructable I would really love to reduce the number of wires in the circuit and come up with a better plan. If I do that I'll share an Instructable on that!

Step 10: Some Pictures of the Indicator

Thank you for reading this Instructable. I hope you enjoyed it as much as I did in making it!

Timeline: Final Test
In the above segment, you can see that as soon as the room gets darker, the "Night Sight" turns ON and as it gets brighter it turns off immediately!

Timeline:Ready to Roll
Some videos I have taken to showcase the indicator in the limelight. All credits to my sisters' cycling for the video!