LED lights for my bike wheels

bike_still

Revolights are a very cool product that illuminates the front and rear wheels on a bicycle.  The only problem for me is the cost; around $220 is a little too expensive, although they are worth it if you can afford it.  I decided to try and make a set of wheel lights for my road bike using SMD LEDs.  A few months ago I got the bright idea to make use of some LEDs that I had laying around.  Designing a quick board and sending it over to Laen’s PCB service got me 30 or so boards for a small cost.  The boards were originally going to be used for lighting the inside of my 3D printer; but after all the work of soldering SMD LEDS and wiring everything together, I reused a scanner backlight that output more evenly.  Since the LEDs were already wired, all I needed to do was attach the lights and batteries with cable ties everything for the initial testing.  Two identical LiPo batteries for a small RC helicopter were used to power the lights on each wheel.  A small switch soldered by the battery acts as a ON/OFF switch.  The first version seems to work fairly well, although it is not waterproof, the next version will be.  I would also like to include a microcontroller to do some extra light

Continue reading “LED lights for my bike wheels”

Furnace went Out

OpenFurnace

     It seems like as soon as I fix something around the house, something else breaks.  The furnace decided to stop working recently and I didn’t realize it until I woke up the next morning.  I decided to see if I could fix it seeing as I replaced the hot-surface ignitor the year before.  After watching the start-up of the furnace, I could see the ignitor was lighting the gas,  but would go out shortly after leaving the blower running.  After doing some research I figured it could be some oxidation build-up on the flame-sensor, giving the control board a false reading.  I removed the sensor and cleaned it with a green scouring pad until it appeared clean.  After replacing the sensor, the furnace seemed to work again and heated the house to the correct temperature.  About a day later I noticed the furnace had started to have the same problem again.  This time it seemed the flame would never light, even with the ignitor glowing hot.  Again I took to the internet for more information on how furnaces function.  Inside they seem pretty simple; a control board, gas valve, ignitor, blower & inducer motors, and various sensors.

After finding a flow diagram on the internet I began to try and troubleshoot the problem.  After a few hours I gave up and decided to call a repairman the next day (it was like 3am at this point).  The repair guy came, tested a few things and concluded it was the furnace control board; he said it would be around $300 to replace.  Knowing I could replace the board myself, I declined the service and just paid for a diagnostic fee, $49.  Next I called a friend who was able to get me a new control board for $79 right down the street from my house; all within 30 minutes of the repair guy leaving my house.

I began by first removing the old control board from the furnace.  Taking pictures allowed me to quickly record the orientation of the various wires attached to the old board.  Once everything was unplugged, I removed the old board from the furnace and set it too the side.  The new board looked to be of much better quality then the old one, and also had status LED’s, which the old one did not.  Once everything was replaced and reconnected I started the furnace up again….it did the same thing.

This time the board flashed the LED with an error code saying the pressure switch was malfunctioning.  I couldn’t get a new switch locally, so I called the another repair place since the first guy was wrong anyway.  After seeing what kind of switch it was, he located one nearby and had it installed in an hour for $100.  In the end I didn’t really need the control board, but it was nice having the status LED and I learned quite a bit about how a small gas furnace operates.

Razor MX500 electric dirtbike…..

A few weeks ago while looking for a better motor for Liam’s go kart, I came across these electric dirtbikes on some forum.  The idea of an electric dirtbike in my neighborhood seemed like a good plan.  I have always wanted to get a dirtbike or enduro-style bike to ride around on.  Two stroke bikes are loud and would annoy the neighbors really fast.  With a little more research I found that a used Razor MX500 would be a cheap initial investment to get into the world of electric bikes.  One weekend of searching craigslist allowed me to pick up (3) MX500’s for $175.

The first bike I picked up worked but the freewheel on the back was shot so the motor could not engage the back wheel.  This freewheel seems to be the problem with the Razor dirtbikes.  A new freewheel was like $12 from some scooter site.  While waiting for it to arrive I decided to use the MIG to weld the freewheel solid.  It might not be the best solution but it allowed me to be able to ride the bike for a quick test.

After the first test my first impressions were that the bike was kinda slow.  Being that it was made for a rider less then 170lbs and I weigh 165lbs, I figured the bike was made for a smaller person.  So we rolled the bike back into the garage and let it charge completely over night.  The next morning I decided to try it before work, not thinking anything would be different.  After a full charge the bike took off pretty fast, and reached a decent top speed.  I need to check my max speed, but it definitively surprised me with its power and speed.  The bike feels like an under-powered pit bike.

While searching for the first bike, I replied to a couple of different adds on craigslist.  The first bike I got for $100 from some kid about 15mins away.  He wanted $150 but asked if he would take $100 because I thought I would have to buy a new rear wheel; overall the bike was in decent condition.  The second two bikes I got from one person way out by Eureka for $75.  These bikes were a little rough with surface rust but looked like to good a deal to pass up.  The add asked for $150 because only one of the bikes worked.  Later he sent me an email saying he couldn’t get either running and would take $75 for the pair, so I agreed.  We picked both bikes up and brought them back to the garage to see what was wrong.  One bike just had a faulty brake cable that wouldn’t let the motor engage.  Once the cable was fixed that bike worked fine.  The batteries and the freewheel was also shot on the second bike.  I also noticed later that the chain was also missing.

This whole time I was already researching how to make it more powerful.  Various people have done extreme things to these little bikes. Stock the MX500 runs at 36V with a 500watt motor.  I tried adding one battery from the second set of bikes to the first to make it 48V.  It ran faster but I returned to 36V in fear of ruining the different sets of batteries.  I really wasn’t too concerned about speed as I was the torque.  The 500watt motor really did not have that much acceleration.  I decided to try finding a bigger rear sprocket first instead of new batteries, motor, controller, etc.  Currie makes a 90 tooth sprocket that would have to be modified for use on the MX500.  Someone posted on a forum to have one custom cut for the bike.  A company out of Ketucky, Rebel Gears custom cuts aluminum sprockets.  So after a few calls I had a 95t and 100t sprocket on order for the MX500.  It took almost two weeks but in the meantime I worked on modding the frame.

First I decided to cut the top battery tower support.

Then a flat piece of steel was welded to the rectangular tube.

Then the whole piece was welded to make it look like top battery tray was just extended.

I also began to weld extra steel rod around the back for looks.  They still need more grinding to make them look better; I have only had the MIG welder for a few months.

I also decide to chop the handlebars and use and old MTB bar welded in place.

After all of the welding the rear sprockets finally arrived.  After rigging some chain together the sprocket went together easily.

Below is a comparison with the new 100t on bottom and the stock rear sprocket on top.  Its quite a bit bigger.

Here a few more pictures of the bike at its current state.

I the future I would like to get the frame powdered coated; I am not really of fan of the red.  Tried painting the plastics with Krylon’s Fusion paint.  I need to do a few more light coats, but it seems to work ok.

Next comes the 48V setup…….

16F877A devBoard

Laen’s PCB Order comes through again with some nice quality boards for a recent design.  I wanted to try soldering a few TQFP microcontrollers in a toaster oven, and ended up using a 16F877A.  Using the 16F877A allowed enough pins to connect quite a few devices together.   Since you get three copies of any PCB that you order, I decided to try and use one for building a scoring controller for an airhockey table.

My basic requirements for the board were:

  • ICSP port
  • LCD character display
  • 7-segment display using a MAX7219 driver IC
  • Thermocouple support using a MAX6675 sensor IC
  • Piezo speaker
  • 2 onboard buttons for input
  • 4 onboard LED’s
  • RS232 I/O via software -> PICBASIC
  • Unused pins brought out to header pins

I then went to work using eagleCAD for the schematic and board layout.  After many changes I finally settled on a design.

The design was then sent off to Laens PCB order for fabrication.  A few weeks later the boards arrived and I began to assemble them. I decided to assemble just one in the beginning to see if they were even going to work.

Here was the build log:

PIC16F877A TQFP Development Board ver.1 Log

****************WARNING****************
ver1 of the development board has a few traces that were not fully routed during design.

Pins E.0 and E.2 need to be connected via jumpers.

The LCD_AnyPin.pbp must be used to allow different pins for the LCD.

The MAX6675 silkscreen is upside down, turn the IC 180 before placement.

The silkscreen by the speaker shows D.6 while it is actually D.7.

The Thermocouple I have is WHT=+, RED=-
*******************************************

4/2/2012:
After soldering the minimum required components, my first attempt at programming via ICSP did not work. The ICSP connector must be placed a certain way; see completed board. Finaly I was able to successfully program the 16F877A via the ICSP, although a program to flash the LED failed.

4/12/2012:
A simple PICBASIC program to flash the LED connected to E.0 initally would not work. I tried various settings of the fuses but nothing seemed to work. While looking over the board layout trying to figure out the problem, I noticed two traces form the onboard LEDs were not fully connected to the PIC! I dont know how this slipped through, but was an easy fix with some small gauge jumper wire. I then decided to remove the 33pF capacitors on the 20mHZ crystal and replace them with 22pF. I also changed the 47uF capacitor on the 7805 with 10uF. After reprogramming the 16F877A again, the green LED began to blink! Now I was finally starting to think the board wasn’t a complete bust. I soldered on the final components and decided to wait until tomorrow to try it.

4/13/2012:
I did not want to start the board without configuring the 16F877A to use the various I/O’s first. My initial test of the MAX7219 did not work. I also noticed the MAX6675 was now becoming very hot. I removed the MAX6675 until I have more time to look at it in detail. Initial thoughts are wrong routing of signals. I finally got the MAX7219 to work. After moving the code over from the PID program I noticed there is a subroutine “Transfer” that directly calls the PORTS instead of using a variable. Once both were changed to their corresponding ports the 7segment display jumped to life! The MAX6675 still wasn’t working properly.

4/15/2012:
I finally figured out the cause of the overheating MAX6675. The artwork that was silkscreened on the PCB has the chip orientation wrong. Once I noticed this I de-soldered the old chip and placed a new one using  the reversed orientation. This fixed the MAX6675 and now works perfectly. After using the LCD_AnyPin.pbp from Darrel Taylor, I then was able to set the individual pins for the LCD bypassing PICBASICs restrictive settings. So up to this point it seems everything is working that I have tested. I need to check out the RS232 connection and the onboard speaker.

4/16/2012:
The onboard speaker works after noticing the silkscreen is incorrect by displaying port D.6 while it is actually D.7.

4/21/2012:
Everything seems to be funtioning on the second board I built. I used SMD LED’s instead of thru-hole. The SMDs I had can be soldered nicely between the pads for the thru-hole versions. The finished board looks much nicer than when using the SMD LED’s. While building the second board I had trouble getting it to reliably start. It seemed intermitent at best with no reason. Later I narrowed it down to either the crystal or the trim capacitors near it. Once the trim capactitors were removed The board seemed to work perfectly. I read something a while back that mentioned the capactince? of the entire board can allow use of no trim capacitors. Whats weird is the first prototype has the capactitors and works fine.

Here are some images of the assembly process:

PCB just after coming out of the oven

After installing basic components to allow use of the ICSP

Completed development board with LCD removed

Picture of the bottom side showing the wire jumper fix

Completed board w/LCD attached running a demo

Running a test of the MAX7219 7segment driver

Using PICBASIC, I created a demo for the board testing various features including the LEDs, speaker, thermocouple, and the 7segment display. Ill post the code in another post.  Right now I am trying to implement a simple menu system for selecting various tests.

Final thoughts on the project:  I was impressed the board had only a few mistakes that were fixable; especially for not testing the design first via simulation or using a breadboard.

MAX6675 Thermocouple Board

The MAX6675 pcbs I had manufactured finally got populated. These will be used in conjunction with a master station running PID control software.  The boards were created with EAGLE Light.  This is the first time I have ordered a pcb that I had designed in EAGLE.  I didn’t have time to build a prototype first, so I just ordered them anyway.  I used Laens PCB Oder for the boards.  They were reasonably priced and you get (3) copies of each board that you order.  The board has (4) MAX6675 chips with decoupling capacitors for each.  Each 6675 has a 2-pin screw terminal for attaching the thermocouple.  The MAX6675 uses onboard cold-junction compensation, and is located in close proximity to each screw terminal.  The chips are controlled via the I²C bus and share CLK and DATA pins while being selected with individual CS pins.  Everything is brought out to a 8-pin SIP connector that I can plug into a breadboard or connect into a larger master unit.

Here is the EAGLE layout of v1:

Here is the datasheet for the MAX6675.

I’ll post some PICBASIC code eventually that shows it in use with a 7-segment display using another board I had ordered at the same time.

PICBASIC and the SAA1064 Seven-Segment Module

A while back I purchased an I2C compatible 4-digit seven-segment module on eBay for next to nothing. The description said arduino compatible, so getting it to work with PICS should not be a problem.  The display module is based on NXP SAA1064 I2C controller.  The datasheet for the SAA1064 can be found here.  The modules I2C device address is factory-set at %01110000, or $70.  Initially, I2CWRITE seemed like the logical choice for getting the device to work.  For some reason I was unable to get I2CWRITE to work, and had to manually send commands via the SHIFTIN/SHIFOUT commands.  After the 16F88 was up and running on the breadboard, went about hooking up the module.  There are 4 pins on the board: VCC, SDA,SCL,GND.  VCC and GND were connected to their respective pins.  The SDA and SCL pins were then connected to PICs B.2 and B.3 pins with pullup resistors on both pins. 

Before the module can display anything the SAA1064 has to be initialized.   

First the I2c communication has to be started, which accomplished by calling the subroutine I2C_START:

 I2C_START:              
    HIGH SDA
    HIGH SCL
    LOW SDA
   RETURN

The SDA and SCL pins are both set HIGH, then the SDA is brought LOW, which lets the I2C bus know data is comming.

The SAA1064 expects the next byte to be the device byte, followed by the instruction byte, followed by either a control or data byte.  When the circuit is first powered on the SAA1064 must be initalized.   So first the device byte is sent:

i2c_out = %01110000 : GOSUB I2C_TX

 The program contains a variable i2c_out, that gets loaded with the byte to be shifted out.  The subroutine I2C_TX is then used to shift that data out:

I2C_TX:                           
    SHIFTOUT SDA,SCL,1,[i2c_out]  
    SHIFTIN SDA,SCL,0,[i2c_ack\1]          
    RETURN

SHIFTOUT is used to send the i2c_out byte, MSB first.  Next SHIFTIN is used to recieve the ACK bit from the SAA1064.

Next the instruction byte needs to be sent.  Refer to the datasheet for bit settings of the instruction byte.

 

The instruction byte is like a pointer to where the next byte is put on the SAA1064.  A value of %00000000 sets the pointer to the control register.  So the i2c_out is loaded with %00000000 and shifted out:

i2c_out = %00000000 : GOSUB I2C_TX

Now that the pointer is set to the control register, the control byte can be sent.  The control byte allows different settings of the chip to be used.  A value of %00010111 turns on dynamic mode, turn off blanking on segments 1-4, and sets the segment power at 3mA.  So again the i2c_out variable is loaded with  %00010111 and shifted out:

i2c_out = %00010111 : GOSUB I2C_TX       

Now that the control byte is sent, the I2C communication can be ended by calling the I2C_STOP subroutine:

I2C_STOP:
    HIGH SCL
    HIGH SDA
    PAUSE 1
   RETURN

The I2C_STOP subroutine brings the SDA pin high again which ends the I2C transmission.  Now the display is set up and is ready to use.  A simple example of use:

First use LOOKUP to translate segment bits into actual decimal numbers.  This is where things could be different depending on who built your module.  Mine came with a segment key:  


 
0 = b
1 = DP
2 = a
3 = c
4 = e
5 = d
6 = g
7 = f

 

 

So using a lookup table, bits can be translated into digits:

LOOKUP i, [189,9,117,109,201,236,248,13,253,205],seg_val

If the value (4) is loaded into the i variable, then the LOOKUP command would load (201) into the seg_val variable.  (201) is the decimal equvilant of %11001001, which turns on segments f,g,c,and b; or the number (4) on the display. Now the value can be sent to the display:

GOSUB I2C_START
   i2c_out = %01110000 : gosub i2C_tx 'device byte is sent
   i2c_out = %00000001 : gosub i2C_tx 'instruction byte is set to point to digit 1
   i2c_out = seg_val : gosub i2c_tx 'seg_val is sent to display
GOSUB I2C_STOP

First the I2C transmission is started.  Then the device byte is sent, followed by the  instruction byte %00000001, which sets the pointer to the first digit.  Then seg_val is then sent.  Finally the I2C transmission is stopped, and the number 4 should be displayed. 

I cant seem to get the auto increment to work, so each digit has to be pointed to manually with the instruction byte.

Here is the entire PICBASIC code for a PIC16F88, which counts from 0-9, on each of the digits:

-------------------------------------------------------------------------------
'// for 4MHZ
DEFINE OSC 4
OSCCON=%01101000
'// for 8MHZ
'DEFINE OSC 8
'OSCCON=%01111000
While OSCCON.2=0:Wend
CMCON         =  7                 '// PORTA = digital I/O
'OPTION_REG.7  =  0                 '// Enable PORTB pull-ups
ADCON1        =  7
ANSEL=%00000000                    '// set all analog pins to digital
ANSEL = 0                          '// disable ADCs
TRISB.3 = 0
TRISB.2 = 0
'----------------------------------------------------------------------------
led         var PORTA.1
SDA         VAR PORTB.3
SCL         VAR PORTB.2

i2c_out     VAR BYTE        'data to sent over I2C bus
i2c_ack     VAR BIT         'acknowledgement bit
i           var byte
segment     VAR byte
seg_val     var byte
'----------------------------------------------------------------------------
gosub startup 
GOSUB init_display   'initialize the display module
main:
   GOSUB COUNTER
   goto main
   END
    
counter:
    for i = 0 to 9
        lookup i, [189,9,117,109,201,236,248,13,253,205],seg_val
        for segment = 1 to 4
              GOSUB I2C_START
              if segment = 1 then
                 i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000001 : gosub i2C_tx
                 i2c_out = seg_val : gosub i2c_tx
                 gosub i2c_stop
              endif
              if segment = 2 then
                 i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000010 : gosub i2C_tx
                 i2c_out = seg_val : gosub i2c_tx
                 gosub i2c_stop
              endif
              if segment = 3 then    
                 i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000011 : gosub i2C_tx
                 i2c_out = seg_val : gosub i2c_tx
                 gosub i2c_stop
              endif
              if segment = 4 then    
                 i2c_out = %01110000 : gosub i2C_tx : i2c_out = %00000100 : gosub i2C_tx
                 i2c_out = seg_val : gosub i2c_tx
                 gosub i2c_stop
              endif
          next segment
        pause 100 
      next i
    return    
init_display:           'initialize the SAA1064 module and flash all segments
    GOSUB I2C_START     'Start the I2C communication
       i2c_out = %01110000 : GOSUB I2C_TX        'send device byte
       i2c_out = %00000000 : GOSUB I2C_TX        'send instruction byte 
       i2c_out = %00011111 : GOSUB I2C_TX        'send control byte    
    GOSUB I2C_STOP      'Stop i2C transmission
    pause 1000          ' leave segments on for 1 sec then turn off
    
    GOSUB I2C_START
       i2c_out = %01110000 : gosub i2C_tx
       i2c_out = %00000000 : gosub i2C_tx
       i2c_out = %00000001 : GOSUB I2C_TX
    GOSUB I2C_STOP
    pause 500
    
    GOSUB I2C_START
       i2c_out = %01110000 : gosub i2C_tx
       i2c_out = %00000000 : gosub i2C_tx
       i2c_out = %00010111 : GOSUB I2C_TX
    GOSUB I2C_STOP
  RETURN
I2C_START:              
    HIGH SDA
    HIGH SCL
    LOW SDA
   RETURN
 
I2C_STOP:               'I2C stop (terminate communication on I2C bus)
    HIGH SCL
    HIGH SDA
    PAUSE 1
    RETURN
 
I2C_TX:                           'I2C transmit -> send data to the slave
    SHIFTOUT SDA,SCL,1,[i2c_out]  'Shift out “i2c_out” MSBfirst
    SHIFTIN SDA,SCL,0,[i2c_ack\1] 'Receive ACK bit          
    RETURN
--------------------------------------------------------------

Fume extractor for soldering….

  After making more pcb’s to solder, I finally decided it was time to build a fume extractor.  With all the spare parts I have laying around it wouldnt be that hard to contruct.  I etched a small pcb for using an LM317 voltage regulator as a ghetto speed control for a 70mm PC cooling fan.  The box was constructed out of various scrap pieces around the basement.  With everything finished I think a coat of paint will help, and a charcoal filter from the local Salvation Army will complete the project.