Archive

Posts Tagged ‘SparkFun’

Hacking Tiny Servos

Thought I would blog about hacking the 9g servos from SparkFun and converting them to continuous rotation since I’m performing said hack for an upcoming project.  I’m sure there are more and better instructions on how to do this, but I’ve looked at tutorials before for larger servos and noticed these little guys are a bit different.

What I’m doing is changing a servo that normally has around 90-120 degrees of motion to have full 360 continuous rotation.  Instead of the servo reacting to the standard PWM signal as a position signal, it will now act as a velocity signal with full forward/stop/reverse control!  Best of all, when people tell you the servos on your YT-1300 look like a piece of junk, you can tell them you’ve made a few special modifications yourself.

Apology in advance for the images – I promise to never use my cell phone cam for blogging again!  It’s abysmally unfit for close up pictures of electronics.


Take the servo apart

The black circular piece with the shaft in it, next to the gears, is the potentiometer. Two stops are there, two more are on the case piece to the left of it.

Remove the sticky label (goo-be-gone is needed) and remove the screws.  You’ll likely need a jewelry screw driver.  Pull all three sections apart, remove the gears, and remove the white plastic cover over the potentiometer.  Easy peasy.

Cut out the stops

I’m running on memory, so feel free to correct me in comments if I’m wrong.  I recall this as the part that’s different from the standard sized servos.  There are stops on the potentiometer and you practically have to cut out half of the pot to get it to rotate properly.  This is because the pot shaft is used as the axis for the gears and external drive shaft.  Boo to the man that designed it this way, unless it made it significantly cheaper.  In that case, yay… but boo.

Warning: The plastic on the pot is EXTREMELY brittle.  If the pot case crumbles, your servo is trashed.

Proceeding onward.  You’ll see two plastic stops in the pot – cut it out in small pieces.  Once that’s gone, you’ve got to remove the potwiper.  The copper-colored middle terminal of the pot should come out with a little force at this point.  There are a couple of “C” shaped metal tabs that will come out with it.  Now cut the entire terminal off and leave the wire hanging for now.

On one of my servos, I cut it out without pulling the shaft out.  On another, the shaft hole cracked cand the whole shaft came out which made this easier – but I’ll have to report later as to whether it still works well or not.

You also need to cut out the springy piece.  You can’t remove it completely, it appears to be connected with the shaft itself, so you’ll need to cut it flush against the remaining metal flange.

The final stop that has to be cut is on the actual case, just inside the hole where the shaft exits the case.  Flush cutters make quick work of this, but an Xacto knife could probably work too.

Solder resistors in place of pot

With the middle terminal removed and cut off, solder resistors between the two terminals and then solder the middle terminal wire to the middle of the resistors.

So that the potentiometer has a reference point for its control loop, we need to solder resistors in place of the pot.  I used two 10K resistors, which will make the signal that would have centered the servo be the stop position.  Positions signals right from the signal will be forward, and positions left from the signal will be reverse.

Solder the two 10K resistors (surface mount or 1/8W or smaller should fit) in series between the two remaining posts.  Then solder the currently-floating middle terminal wire in between the two resistors.

Put the servo back together

Pretty straightforward.  Do step one in reverse.  The gears may feel like a puzzle, but there’s only one way they fit.  Lastly, be careful with the screws – they strip out pretty easy.


Shazaam!  Full control of a motor with great torque/gear ratio with only a half hour’s worth of effort.

ZephyrEye Rev2: Board Layout in Eagle

5 March 2010 3 comments

An update on Rev2 status:  The schematic is looking pretty good, albeit there are probably still some errors that will seep up to the surface.  I’ve started on the board layout, which will also help uncover any schematic errors.  Today I’d like to go through the process I usually use to layout circuit boards in EagleCAD.

In case anyone was wondering if I was kidding about the cat and laser pointer thing, here’s a great chance to find out.  Download the schematic by itself, open it in EagleCAD, and click the “Board” button (5th from the left on the toolbar), and try laying out the board.  Make sure and give yourself some time (a day or two without sleep should do it), and dig in!

So here are the steps I use when laying out a board.  After the schematic has been reviewed several times (preferably by someone capable and also familiar with the project, not just by yourself), click the “Board” button (location described above).  What Eagle does here is it takes all of your components and puts them next to a random outline.

From here, let’s just go down the list.  Note that this is just what I do for boards like this.  It gets the job done very quick, with decent quality, but others do things different and may agree or disagree with this approach – I’d love to hear what others do in the comments!

  1. Draw a circuit board outline
  2. Group components into proper areas
  3. Manually route critical traces
  4. Autoroute remaining traces
  5. Manually fix autorouter mistakes (sometimes, the autorouter makes no sense!)
  6. Run Design Rule Checks against the board
  7. Redo steps 3 through 6 if necessary
  8. Send design to the boardhouse

1) Draw a circuit board outline.

If you don’t care what size your circuit board is, this is a very easy step.  Take the default, and shrink or expand it as you get closer to finishing step two.  Chances are, however, you should make careful considerations about your intended enclosure(s) for the circuit board.  Don’t skip this step lightly, or you’ll pay for it exponentially down the road.  Case in point: ZephyrEye Rev1, from the side as shown below.  Originally I thought I would use a different case, but it was too bulky and looked horrible.  But it didn’t exactly fit in my backup case, either:  I had to cut out the side just to get it to fit.

This is what happens when you don't think carefully about enclosures ahead of time ...The result: Ugliness.

I’ve downloaded the manufacturer’s datasheet for the enclosure, and following it’s recommendation outlined the board to maximize the PCB surface area – I’m going to need it all to get it all the features packed into this tiny little enclosure.  Either modify the existing outline, or draw using wires on the “Dimension” layer 20.  The board house will router your PCB following this outline.

Another item I always forget (and actually just remembered while writing this), is mounting holes.  Some people use vias connected to ground, while others use drill holes.  I usually prefer vias, because you can set the diameter of the copper around the via and avoid routing other traces within range of the head of the screw.  It also lets you ground your circuit board to the enclosure, which is common with metal enclosures.

2) Group components into proper areas.

For most components this is pretty straightforward.  Put all the schematic elements in the same area: an IC, supporting passives, and related supporting circuitry.  But you’ll also need to take into account any special needs of that part of the circuit:

  • Sensitivity to noise
    • The digital compass would potentially have issues if placed near the transmitter, or near any high current wires due to the magnetic field around a current-carrying wire.
  • Proximity to the edge
    • The GPS circuit needs to be near the edge because it has an antenna.  You can’t trace antenna wires very far without serious signal degradation, so it gets a special spot.
    • Most components that need to be near the edge are there because they need to match up with enclosure features – measure these things out carefully when necessary.
  • Proximity to other chips it needs to communicate with
    • If you can, put inter-communicating chips near each other.  There’s considerable flexibility on this point, depending on the protocol, the speeds they communicate at, and sensitive areas that these signals must avoid.
    • Example: If you were routing wires carrying USB 2.0 at 480MHz, it would be bad news for both other chips on the board as well as your USB signal integrity if these were long.  In fact, at this high of speed, there are very specific routing guidelines that must be followed.
  • Speeds of signals that will travel on the signal wire
    • Crystal wires should always be very short.  Once you get a signal that will be up in the megahertz range, the shorter it can be the less noise you’ll get at other locations on the board.  The trace carrying the signal can act as an antenna if it is too long.
  • Analog signals need special consideration.
    • Usually, you’ll want to avoid routing communication wires (RS232, SPI, or I2C) near analog wires.  These communication wires will put noise into your analog signals, causing headaches and very weird errors when debugging the board.
    • Antenna signals are analog of the most sensitive kind, and usually need to be a specific width if they travel very far.  You may also need to “impedance match” the trace to avoid distorting the signal.

That’s not an exhaustive list, and not detailed by any stretch of the imagination.  Google for more details on any above item you fear a board you’re laying out may have issues with.  Datasheets will have very specific layout requirements as well, many have a PCB layout guide for the chip.  Lastly, check for reference designs.  These are great to follow because you know they have been proven.

Prior to routing, all the components should be grouped into logical areas.

You’ll notice the schematic is already outlined in this way.  For example, the digital compass (HMC5843) should be placed somewhere within the outline that will be away from high-current lines (e.g., lines which may induce magnetism and noise).  I picked a corner away from everything else for this guy.  It was pretty easy to look at the schematic and see that I needed to pull in C31, C34, C40, R11, and R19.  Quickly looking at the air wires, I put them in an order that seemed like would work once the traces were routed.  Then I did more or less the same for the remaining component “groups”.

Notice the surface mount components are on top as much as possible – this makes it easier to assemble, particularly for pick & place machines and/or if you are going to bake it in a reflow oven.

3) Connect Vcc, GND, and critical traces

Vcc and ground traces go first.  Usually, I go for a ground plane on top.  Some people do Vcc planes on the bottom – I’m not a big fan of this, but I have done it.  Make sure the traces are wide enough to carry the current they need to (this calculator may come in handy) – in general, they are but it’s better to make wires that carry a lot of current be thicker anyway, no sense having a bunch of fuses around the board.  I estimated my max current delivered to this board to be less than 250 mA, but I still use .024″ traces for VBAT, and 0.16 for a few of the VCC traces.

For a few of the components, you’ll also want to trace things out before you let the autorouter have its way.  You can also quarantine areas as off-limits to the autorouter for sensitive areas.  For example, the GPS circuit is pretty sensitive, especially with regards to the RF ground plane and the antenna trace.  I routed this area up ahead of time.  To make sure  areas like this aren’t touched, you can then place polygons on the top and bottom restrict, keepout, and vRestrict (for vias) layers to manage the autorouter.

4) Autoroute remaining traces

This step has a few tricky items that can make the difference between a successful autoroute and a complete failure autoroute.  Pay close attention to the setup!  Here are the steps I used:

  • Save before you start! You will NOT be allowed to use “Undo” commands after you start the autorouter.  I usually save a separate copy before I start just to be safe.
  • Make sure your design rules are set up correctly as the autorouter follows these rules while routing traces.  Use the toolbar or click “Edit -> Design Rules…” to open the DRC dialog.  Set up the rules to follow your intended board house’s manufacturing guidelines and minimum tolerances (check their website).  Here are the ones I modified from the default:
    • Clearance Tab:
      • I set all clearances to 8 mils.
    • Distances Tab:
      • Copper/Dimension: This is the minimum distance between any copper (whether a trace, polygon, or component) and the board outline on the dimension layer 20.  I set it to 10 mils.  If you route traces too close to the edge of the board, they may get cut or damaged.
      • Drill/Hole: Distance from anything to a hole on the board.  Set to 8 mils.
    • Sizes:
      • Minimum Width:  This is the minimum width of a trace, and the autorouter will use this for everything.  10 mils is a good minimum if you have plenty of space – I used 8 mils.
      • Minimum Drill: This is the smallest drill size available from your board house.  20 mils for me.
    • The rest of the defaults generally work fine for me, but make sure you’ve met all your board house requirements before continuing.
    • Click “Apply” and then either “Check” or “Cancel”.  It’s a good idea to check your work so far to make sure you pass off a clean board to the autorouter.
  • Now click on the “Tools -> Auto…” (or use the toolbar) to open the Autorouter Setup dialog box.  Make the following changes according to your design needs:
    • Routing Grid: Here’s the deal.  The larger the grid size, the less time it takes.  But the autorouter will only consider trace joints and intersections every 50 mils.  So for surface mount components pins at, say, .5mm pitch (pin centers are .5mm apart), the autorouter will fail to connect most pins.  It will also have issues in congested routing areas.  On the other hand, using a 1 mil grid will take forever.  I used 2 mil routing grid – It took about 30 minutes.
    • Change Top and Bottom preferred routing directions if desired.  I haven’t found this to make a big difference in actual implementation, just make sure you don’t pick two parallel directions unless you want issues.
    • To be honest, I’ve never bothered playing around with rest of the settings, or the optimization settings.  I’m sure there are some advantages that can be made here, but I’ve never dove in.  Feel free to comment if you know how to change these to some advantage!

The Rev2 Main Board after being autorouted and cleaned up. Notice a few parts have moved a little to allow better routing, but not many.

Once everything is set up, save again and then hit the “OK” button.  Alternately, if you only want the autorouter to work on a particular subset of traces, use the select button and then hit the green stoplight button on the toolbar to go.  Be forewarned that the autorouter will ripup and retrace ONLY its own traces, and traces there prior to beginning the autoroute will remain untouched.  This can be a problem, especially if you have cut off certain sections of the board with traces on both the top and bottom, or have routed so close to surface mount pins the autorouter cannot place  a via to get around it.

In situations like this, and sometimes just due to trace density, sometimes the autorouter just can’t find a path for all the traces.  These will be left as airwires for you to manually route…

5) Manually fix autorouter mistakes

The Autorouter makes as much sense sometimes...

Sometimes, the autorouter just doesn’t make any sense.  I couldn’t help but post this picture – it’s a classic.

But seriously, sometimes the autorouter just does ridiculous things.  Traces have random and startling paths, take weird angles, overshoot and then overcorrect, etc.  Check through the history of the Rev2 cad files for examples.  You’ll want to shorten most of these traces if you can, take out the weird angles, and fix any traces that went through places they shouldn’t have.

And the autorouter generally uses a LOT of vias.  Vias can actually cost you extra if you use too many from some board houses, because they take extra time to drill and plate in the manufacturing process.  So minimizing vias is important.  You can usually clean a few off manually with a little effort.

It took about 30 minutes to finish the autoroute, because my routing grid was so small.  Before the first optimization step, it had around 320 vias.  Youch!  By the end, however, it was down to around 170.  Go optimizer!

It also left about 7 traces for me to finish by hand.  Most of them were because the ground plane polygon had “fallen apart”, meaning there were so many traces that parts of the ground plane had become separated and were not longer interconnected.  Many were fixed by pushing and pulling vias and traces around.  On a few, though, I had to place vias and bottom side traces that jump under traces that cut up the ground plane to make the connection.

6) Run Design Rule Checks against the board

This step is CRITICAL!  Don’t even consider sending the board off without checking your board against the design rules.  Since you’ve already got the DRC rules setup, just hit the “Design Rule Check” button on the toolbar to run it.  It’s pretty straightforward: Anywhere you have traces that are too close or overlap, parts off the boundary, or drill holes that go through traces or components, you’ll get an error that you’ll have to fix by hand.

This isn’t too bad usually, but in densely routed areas can sometimes be a little tricky.  Just use your elbows, push things out, and make some room.

7) Redo steps 3 through 6 if necessary

Well, as hard as all this has been, you may find something that needs changing.  Say you forgot a critical component, or left off a significant number of traces.  Sometimes you can add these things in after the fact, sometimes this is as practical as putting Jabba the Hutt on Jenny Craig.

If you have to, don’t resist starting over.  The command to get this to happen quickly can be typed into the command bar: “ripup ! ;”.  This will ripup everything, so if there were certain traces you wanted to keep the alternative is selecting the traces to leave alone one signal at a time by leaving off the semicolon, then hitting the green stoplight to execute the command.

If you’re happy with the board, then congratulations!  The next step is to get someone to review your board layout.  A fresh set of eyes makes all the difference.  But don’t be disappointed if, even after several reviews, it comes back with a few hardware bugs.  Have Xacto knife and patch wire ready ;)

8) Send board to boardhouse.

There are a lot of boardhouses, each with different pros and cons.  Here’s a list of other houses I’ve heard good things about:

  • Personally, I use PCBExpress because of proximity – They do small, low-feature two layer boards for pretty cheap, and they ship ground for free.  Since they are also located in Oregon, I get them in two days.  They also accept Eagle files directly – no need to generate Gerbers.
  • I’ve heard good things about Advanced Circuits.
  • BatchPCB is related to SparkFun.  This one is pretty cheap @ $2.50/sq in (plus setup fee), but takes a while to get your boards back.  Time flexibility = lower cost boards.

All of the above have Internet order options.  Just upload your file, answer a few questions (usually about layers), pay for it, and you’re done.  Usually, this is when I put together my final bill of materials and get the parts ordered so they arrive about the same time as the board.

Well, that just about covers it.  I’m sure I forgot something, so as usual feel free to remind me or ask questions in the comments.

ZephyrEye: Parts List

11 February 2010 2 comments

So, the stats tools on WordPress are kind of impressive … and useful at correcting idoits like me.  I’ve talked all around it, but I noticed I haven’t released an actual bill of materials and noticed quite a few people have been searching for it.  Maybe they want to build a ZephyrEye?  I’ll try to do my best to appease the masses.  It’s been quite a while since I actually built the hardware, but here it goes…

Lucky for me, and anyone else using EagleCAD, there’s a handy User Language Program (ULP) called bom.ulp that autogenerates a BOM.  It only lists items that are actually on the schematic, however, so don’t forget things: the LCD connector denotes you should also buy an LCD display.  I’ve never made that mistake though.

Partlist exported from /home/brad/Development/zephyreye/trunk/cad/ZephyrEye Rev0.2.sch at 2/11/10 1:32 PM

Qty Value Device Parts
2 LED1206 LED1, LED2
1 LIPOLY-GEN BAT1
1 PINHD-1X2 MIC
1 POWER_JACKPTH PWR
8 TAC_SWITCHPTH SW_DOWN, SW_IN, SW_LEFT, SW_OK, SW_ONOFF, SW_OUT, SW_RIGHT, SW_UP
1 .01uF C-USC0603K C5
7 .1uF C-USC0603K C3, C7, C17, C18, C21, C22, C23
2 1.5K R-US_R0603 R4, R7
1 1K R-US_R0603 R1
3 1uF CAP_POL1206 C8, C9, C12
1 2.2K R-US_R0603 R2
2 2.2uF (TANT) C-USC0603K C14, C15
1 4.7K R-US_R0603 R9
1 8MHz CRYSTAL XTAL-MCU
4 10uF CAP_POL1206 C1, C2, C6, C10
1 10uH INDUCTOR0603 L7
2 18pF C-USC0603K C19, C20
1 22K R-US_R0603 R55
2 100K R-US_R0603 R5, R54
1 100pF C-USC0603K C11
3 470 R-US_R0603 R6, R8, R16
1 470K R-US_R0603 R3
2 470pF C-USC0603K C13, C16
1 1000pF C-USC0603K C4
1 AVR_SPI_PROG AVR_SPI_PROG HDR1
1 BC108B BC108B Q1
1 DATAFLASH ATMEL_DATA_FLASH IC2
1 EM408 EM408 GPS
1 MAX1555 MAX1555 MAX1555
1 MBRA140 DIODE-DO214AC D1
1 MEGA128-A MEGA128-A IC1
2 MIC5205 V_REG_LDOSMD VR1, VR2
1 NOKIA6100_LCD NOKIA6100_LCD LCD
1 TPS61040 TPS61040 VR_LCD
1 XBEE-PRO XBEE-PRO XB1

Most of the “primary” components are from Sparkfun, with most of the passives, voltage regulators, etc. coming from Digikey.  So, on top of this list, you’ll also need:

If anybody is seriously interested in making one of these guys, let me know.  If at least 10 people are interested, I would be willing to make kits at cost (should be ~10-20% cheaper), and help those wary of the SMT soldering (for a nominal reimbursement).  Keep in mind the programming either comes from you, me, or the community and that the software has basic functionality but is not yet complete.  Also, you’ll want at least two (unless you want to use it for something other than paintball/laser tag gaming).

Note: I’ve started adding a few product links in.  As I have time, I’ll fill in the rest.  Feel free to help out in the comments if you find links to products (from SparkFun or DigiKey generally) before I do.

ZephyrEye: LCD functions

11 February 2010 Leave a comment

So, how do I get all these different components to play nicely together?  Lots of time in the datasheets, browsing forums for tips, and a perpetual lack of anything better to do.  That’s because of the inherent coolness of the project, obviously, and not from lack what “y’all call da social skills“…

I’ll be going through each of the components in the chip and talk about how I interfaced them to the ATMega128 AVR microcontroller.  I’ll try to give enough detail so that someone could rewrite this in a different language if they felt like it.  Once the component interfaces have been described, I’ll go through and describe the remaining functions (menuing, GPS, games, etc.).

This handy little LCD display is pretty easy to use.  SparkFun sells them standalone as well as with a sweet little breakout board, which handles the hard to solder connector and funky backlight voltage nicely, allowing just about anybody with a spare micro lying around to use this display in their projects.  Here are some simplified pin descriptions (but remember the datasheet is the final reference) for those setting up their own display.

  • 1) V_digital: Supply voltage for internal logic circuitry.  Should be separate from V_display.
  • 2) LCD_reset: Resets the LCD.  Necessary for communications.
  • 3) DIO: Data input pin, connect to the MOSI line of your MCU’s SPI hardware.
  • 4) SCK: Serial clock input pin, connect SCK line of your MCU’s SPI hardware.
  • 5) CS: Connected to the chip select line of your MCU’s SPI hardware
  • 6) V_DSP: Display voltage.  This supply voltage is the one that actually drivers the liquid crystals, and therefore needs to be very solid.  The datasheet recommends it has its own voltage regulator, which is not always necessary (it can be tied to Vcc) but I have conceded as it reduces flickering.
  • 8 & 9) GND & LEDGND: Connect to ground.
  • 10) V_LED: White LED Backlight voltage.  +6.8V required to drive these little suckers.  I’ve used the TPS61040 boost regulator to do this, it works nicely.

Note that pin 7 is NC.  It’s also worth pointing out, since this is a battery driven project, that it’s useful to have enable lines connected to GPIO pins on your MCU.  In particular, I’ve been pleased that the +6.8V regulator can simply be turned off when the display is dormant – this saves between 40 and 60 milliamps, which can extend battery life a LOT.

BASCOM-AVR has some very nice routines to use knock-off cell phone displays with the Phillips and Epson chipsets.  However, it didn’t quite work with this particular display from SparkFun so well.  Luckily, I’d already been using this display for a while before Bascom added a library for it, and by using my init routine after calling theirs, it seemed to work out OK.  Here’s the relevant pieces of code (remember, the code can be found on the Google Code repository).

If this LCD worked directly with BASCOM, setting it up would be easy peasy:

'*******************************************************************************
  'Configure Display
$lib "LCD-epson.LBX"                                        'Library for LCD screen
Config Graphlcd = Color , Controlport = Porte , Cs = 5 , Rs = 6 , Scl = 3 , Sda = 4
'*******************************************************************************

I had to add on my custom init routine to get things to work right, as well as a few helper functions:

'************************************************************
'Sends initialization data to LCD screen
Sub Init_lcd()
   Lcd_cs = 0

   Waitms 10

   Snd_cmd Disctl
   Snd_data &H03
   Snd_data 32
   Snd_data 12
   Snd_data &H00

   Waitms 10

   Snd_cmd Comscn
   Snd_data &H01

   Snd_cmd Oscon
   Snd_cmd Slpout

   Snd_cmd Volctr
   Snd_data 5
   Snd_data &H01

   Snd_cmd Pwrctr
   Snd_data &H0F

   Waitms 100

   Snd_cmd Disinv

   Snd_cmd Datctl
   Snd_data &H00
   Snd_data 0
   Snd_data &H01
   Snd_data &H00

   Snd_cmd Rgbset8                                          'Set up the color pallette
   'RED
   Snd_data 0
   Snd_data 2
   Snd_data 4
   Snd_data 6
   Snd_data 8
   Snd_data 10
   Snd_data 12
   Snd_data 15
   'GREEN
   Snd_data 0
   Snd_data 2
   Snd_data 4
   Snd_data 6
   Snd_data 8
   Snd_data 10
   Snd_data 12
   Snd_data 15
   'BLUE
   Snd_data 0
   Snd_data 4
   Snd_data 9
   Snd_data 15

   Snd_cmd No_op

   Snd_cmd Paset
   Snd_data 2
   Snd_data 131

   Snd_cmd Caset
   Snd_data 0
   Snd_data 131

   Snd_cmd Ramwr

   Clr_scr 255

   Snd_cmd Dison

   Waitms 200

   For B = 0 To 140
     Snd_cmd Volup
     Waitms 2
   Next I
End Sub
'*******************************************************************************

Wow, I should have commented that a LOT better … bad Brad! (hitting myself with rolled up newspaper)

Here’s the helper functions.  Normally I’d just refer you to the code, but for those of you trying to get this LCD to work, using the 9-bit frame is a little tricky.  I will refer you to the code for pin definitions and constants, however.  I ended up bit-banging it – YMMV.  Be careful with the polarity and phase of the SPI signal, it’s very particular.  Lastly, note the syntax of BASCOM-AVR for addressing a bit in a byte is the dot operator (e.g. Dab.7 returns the value of the 7th bit of the byte variable Dab).

'*******************************************************************************
Sub Snd_data(byval Lcddata As Byte)
  Lcd_sck = 0
  Lcd_dio = 1                                               'Data = 1
  Lcd_sck = 1

  Shiftbits Lcddata
End Sub
'************************************************************

'*******************************************************************************
Sub Snd_cmd(byval Lcdcmd As Byte)
  Lcd_sck = 0
  Lcd_dio = 0                                               'Commands = 0
  Lcd_sck = 1

  Shiftbits Lcdcmd
End Sub
'*******************************************************************************

'*******************************************************************************
Sub Shiftbits(byval Dab As Byte)
   Lcd_sck = 0
   Lcd_dio = Dab.7
   Lcd_sck = 1
   Lcd_sck = 0
   Lcd_dio = Dab.6
   Lcd_sck = 1
   Lcd_sck = 0
   Lcd_dio = Dab.5
   Lcd_sck = 1
   Lcd_sck = 0
   Lcd_dio = Dab.4
   Lcd_sck = 1
   Lcd_sck = 0
   Lcd_dio = Dab.3
   Lcd_sck = 1
   Lcd_sck = 0
   Lcd_dio = Dab.2
   Lcd_sck = 1
   Lcd_sck = 0
   Lcd_dio = Dab.1
   Lcd_sck = 1
   Lcd_sck = 0
   Lcd_dio = Dab.0
   Lcd_sck = 1
End Sub
'************************************************************

After that, it’s smooth sailing as all of BASCOM’s internal drawing and text display functions work just fine.  Here’s all it takes to draw the setup screen.  The “splash” picture was included in the program, and is loaded from flash program space.  Pixels are set using the Pset command.  Drawing text at certain coordinates and with a defined forecolor and background is done using the Lcdat command.

'Display Picture
W1 = 0
For Y = 2 To 80
  For X = 0 To 127
    B1 = Lookup(w1 , Splash)
    Pset X , Y , B1
    Incr W1
  Next X
Next Y

Setfont Color8x8

Lcdat 88 , 20 , "Start Game" , Black , Gray
Lcdat 96 , 20 , "Join Game" , Black , White
Lcdat 104 , 20 , "Options" , Black , White
Lcdat 112 , 20 , "Settings" , Black , White
Lcdat 120 , 20 , Unit_name , Gray , White

... (near bottom of program)

'Extra include files - Fonts
$include "color16x16.font"
$include "color8x8.font"
$include "smallfont.font"

$include "zephyreyepic.txt"

So there you have it, how to use the SparkFun LCD display.  Hopefully that helps somebody understand how to use it.

As I’ve stated before, I also hope the lengthy explanation helps get all this converted into AVR-GCC.  As a side note, I would like to develop the component libraries into a more useful place: the avr-libc-corelib project.  This would make libraries for all the components readily available for others to use.

As always, if you have any questions about using this display, feel free to leave comments or email me!

ZephyrEye on Tom’s Hardware

9 February 2010 15 comments

Hmm, my blog hit count is going through the roof … This project must be the coolest thing ever, all your base are belong to me!

Oh wait, the stats beg to differ … Aha, the project was featured on Tom’s Hardware!  That makes sense.

I realize there’s not a lot yet – I’m still catching up!  That being said, please feel free to leave comments.  Is it cool?  Is it useful, in paintball? As a paperweight?  Let me know!  And as always, feel free to ask questions in the comments or email me at nelsobra@onid.orst.edu anytime.

For those of you coming from Tom’s Hardware, I realize the image was a bit of a letdown – my blog at the time of writing was a little short on options for them.  I’m jumping ahead of my original posting plan, but for all Tom’s geeks I thought it might be worthwhile to add a small gallery that goes through the setup screen to help understand the project a little better.

ZephyrEye Video

5 February 2010 Leave a comment

I found some old video I took of the ZephyrEye.   I originally threw it out because it’s blurrier than Han Solo’s post carbon freezing vision, but I’ve annotated it heavily so you’ll get the gist. One of these days I’ll get a hold of a decent camera so I can take a decent video … it’s almost impossible to force a cheap one to focus on the LCD display outdoors well enough to be able to read what’s on it.

Here’s another video, showing just the game setup process.

As always, if anyone has any questions about this project or even just about how to use any of the components I used on this project, feel free to leave a comment or email me!

ZephyrEye: Assembly and Testing

27 January 2010 Leave a comment

So now we’re getting into the nitty gritty: time to put this sucker together!  I actually really like soldering.  It’s kind of like knitting.  You put your soldering iron on a TV tray, turn on the Price is Right and some soap operas, and make wonderful Christmas presents.

As promised, here’s the top side and bottom side of the 2-layer PCB returned from Sunstone Circuits.  I usually go without silkscreen and solder mask (the green coating on PCBs) because it’s cheaper and a little more convenient to solder patches onto.

The best way to test a new circuit board is to assemble and test one section of the circuit at a time.  Of course, I never do this.  But you should.  If you haven’t noticed so far, I have no issue using hypocrisy to control others actions.  I’ll make a great politician someday.

The alternate method that I more typically use is that I will cut traces on the board using an Xacto knife and then put a dab of solder over the cut when I get ready to test it.  Sometimes it works well, sometimes I end up doing a lot of cutting, fixing, cutting, and fixing …  kind of a Michael Scott/Jan Levinson relationship goin on with my boards, snip snap, snip snap …

On this particular project I did a blended approach of the above – I did a few things at a time, and some cutting as necessary.  The first thing you want to solder on is the voltage regulators and associated passives.  Check to make sure you get the voltages you expect with a voltmeter, because if you don’t it could be the end for any chips attached to that voltage rail.

What’s that? VR4, you say?  Where’s that on the schematic? Well, it turns out I didn’t do a great job of specing VR2.  For a while, whenever the XBee transmitted a packet, it would reset the GPS.  Undervoltage!  It couldn’t source the current needed when transmitting.  So I cut Vcc loose from the XBee and tacked on an extra LDO regulator to provide power for it since it draws more current than anything else.  This seemed to fix the problem.  Snip, snap, snip, snap…

The LCD datasheet recommends two separated 3.3V voltage rails, one shared with VCC and one for internal needs, on top of a 6.8V white LED backlight voltage.  The TPS61040 boost regulator worked great for this source.

Next I soldered on the MCU, LEDs, the XBee module, the GPS connector, and all the associated passives.  Touch bases with Starfleet Command by writing a quick program to test that the microcontroller is running.  The best test is the “blinky” test.  If you get the LED to turn on and off, you’ve got things going for you.  If you don’t get a blink or if you notice your one second toggle is actually eight seconds, check the MCU fuse bits.  Shorted crystal leads is typical if you fail to get anything, or check the “divide clock by 8” fuse bit if you get an 8-second “1-second” blink.  Alternately, check that time has not been scaled by LHC tests.

I’ll mention some about the programming, etc., but if it feels like I’m talking about it briefly, it’s because I am.  The next blog topic is programming, where I’ll dive into the programming details, fuse bits, chip communication protocols, etc.

The XBee was the first part to get going.  It’s even easier than a MAX232 chip.  Just connect the UART lines up and start sending bytes.  Whatever you get on one end, you get on all the others (at least in out of the box configuration).  So it’s really great for diagnosing problems early on.  On the other end, I’ve got another XBee chip connected to my computer through an FTDI UART-USB chip.

After I got the XBee transmitting and receiving (transceiving?), I programmed a UART based bootl0ader into the Mega128.  BASCOM-AVR provides a very easy to use and easy to modify bootloader that receives programs via XModem.  It works like a charm with only slight modifications (baud rate set to 38400).  A bootloader acts like a separate program whose sole function is to copy the main program into Flash memory.  It runs at startup, or if called from the main program, and checks to see if it is receiving the a particular byte sequence.  If yes, it does it’s thang.  If not, then it just calls the main program.  This speeds up development time a billion, because I can reprogram it anywhere.  From across the house or across the street even.  Kinda fancy, yeah?

Next, I checked reception on the GPS.  Since the Mega128 has two UARTs, I used one for XBee and one for GPS.  The GPS transmits NMEA strings, which provides localization information.  This one was pretty straightforward, just parse the GPRMC sentence to extra heading, latitude, and longitude info.  And it can be simplified if you assume it’s only used in the Northern hemisphere, which of course, I simplified.  I did add a 2.2K pullup on the GPS Enable line which helped it ride through the power dips during XBee transmission.

Last but not least, the LCD display.  This one took a little bit of soldering iron sorcery to get it to work.  I forgot (gulp!) to connect the data and clock lines on the display.  That makes it a beautiful blue PCB decoration with no function.  If you look closely at the display connector (just north of the AVR), there are two little strands of wire that pull those signals off the 0.5mm pitched (spacing from center of one pin to the next).  I soldered them to a couple of cut out vias and then soldered a strand of ribbon cable to suitable pins on the MCU.  The screens are a little fragile because of this…

Last and, since I almost forgot about it probably least, the battery and charging circuit.  The battery is an 1100 mAh Lithium polymer from SparkFun.  According to my scope, the circuit drew about 250 mA, which if the circuit was optimized to draw all the juice out of the battery, would last for four hours.  In reality, the Low Drop Out (LDO) regulators require about 0.3V about 3.3V to properly regulate, so they will source from 4.2V down to 3.6V properly, but without crunching a lot of math I should be able to get about an hour per charge.  The MAX1555 is a super simple Lithium Polymer battery charger that can charge the battery through either USB or DC power sources.  When the battery is full, it automatically goes into trickle charge mode to keep the battery topped off.  It works perty good.

I just said perty.  My redneck past is always nipping at my heels …

Anyway, the final physical appearance of the jobber looks like this, next to a couple of common objects for size comparison:

And just to make sure things would look right, I programmed in a quick and dirty static screen that represents what the game screen might look like:

Next post, we’ll dig into the firmware.