Archive for February, 2010

ZephyrEye Rev2: Call for Schematic Reviewers

24 February 2010 3 comments

There are a few inevitable truths in this world.  Taxes will rise, Wookies shed all over the furniture, Luke and Leia are related, and there is no such thing as a perfect first draft schematic.

The Rev2 circuit is nearly complete.  It looks AMAZING if I do say so myself.  That’s the problem, though:  I’m inundated with excitement and therefore am unable to find things that are wrong because I don’t want to find any reason that might delay getting the circuit boards back as soon as possible.

I’m calling out for a few extra set of eyes to look over the schematic   If anyone could please go to the Google code, download the Eagle CAD files and take a look, I’d really appreciate it.  If you want to make changes, let me know so I can arrange for them to be merged back in properly.  Even if you’ve never looked at schematics before, take a look and as always, feel free to ask what’s going on in the comments.

This is also a great chance to give suggestions on functionality.  I should add, it may be your LAST chance!  Please give some comments if you think you might ever build one, if nothing else just to say you think it works for what you’d like to use it for.

If you’re not familiar with CAD schematics and circuit board layouts, it might be interesting to look at the history of the .sch and .brd files in the Google Code repository.  By looking at older revisions, you can see the steps taken along the way chronologically.  I commit changes at least at the end of almost every day I work on the project.

The current Bill of Materials can also be found at this Google Docs spreadsheet.  It includes estimated pricing – it currently comes in at just under $200.  A little bit higher than I was hoping, but about the same cost as Rev1 and Chuck Norris (adverbicized) packed with new extra features!

The schematic is hopefully organized well enough for someone not intimately familiar with this project to try and understand one section of the schematic at a time.  The capacitive touch schematic is separate, because it will be a separate board.  The way it works is you put copper pads on the board, glue it to the inside of your enclosure, and it senses you touching it on the outside of the enclosure.  Pretty nifty, and a great way to avoid milling the enclosure.

Please post comments below, or add to the Google Groups discussion page.

ZephyrEye: XBee Bootloader

19 February 2010 Leave a comment

A bootloader is like a program inside of a program.  Almost just like a supervisory program.  Normally, when a microcontroller starts up, it boots to what’s called the “Reset Vector”, which is at address $0000 (the dollar sign means it’s a hex number).  The Mega128 has 128KB, or $FFFF bytes, of program flash, so what we want to do with the bootloader is section out a chunk of program space that works separately from the main program.  That way, the bootloader can wipe out the main program, copy a new program in its place, without wiping itself out at the same time.

The Mega128 has fuse bits that allows you to boot to a different address than $0000 at startup.  So say, for example, you set the fuse bits to boot to $FC00 on powerup.  This points the processor to the program space at 2KB before the end of your memory.  You can put a program here that does whatever it feels like, and then given certain conditions, it will “jump” program execution to the main program, which is found at $0000.

So, in our case, we want the ZephyrEye to have a simple program that waits for a period of time before starting the main program.  Two things can happen during this wait period:

  1. If it detects a particular serial pattern during the wait period, then it knows to expect an incoming program transmission, initiates a reply, and begins downloading the new program.  The new program is written to flash, starting at address $0000.  Once the program reception is complete, the bootloader program jumps to $0000, which starts the main program.
  2. If the bootloader program doesn’t detect the correct serial pattern, then after the timeout it simply jumps to the reset vector at$0000.

Pretty straightforward, right?  A major advantage of using a bootloader is that it allows you to program your device anywhere.  In the case of the ZephyrEye, it also means you don’t have to plug in a serial programmer cable to it, or even own a serial programmer to reprogram it.  This easily cut the development time in half!  It makes it so much easier and quicker to test your code.

BASCOM-AVR provides sample bootloader code.  You can modify this to make it work however you want it to, which I did.  On the ZephyrEye Rev1, I decided to use a 38400 baud rate for the XBee, and I had it connected to UART1.  The BASCOM bootloader uses the XModem protocol, which checks to ensure program integrity during transit.  I won’t dive into that part of it (see repository for full bootloader code), but here are a few excerpts.

This first chunk sets up the bootloader with a few of its settings.

$crystal = 8000000
$baud = 38400


$regfile = "m128def.dat"
Const Loaderchip = 128


#if Loaderchip = 128                                     ' Mega128
 $loader = &HFC00                                        ' 1024 words
 Const Maxwordbit = 7                                    'Z7 is maximum bit                                   '
 Open "COM1:" For Binary As #1
 Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0


Disable Interrupts                                          'we do not use ints

So, now we’ve got a serial port open on channel #1, with the UART correctly configured to communicate with the XBee modem.  Notice that interrupts MUST be disabled.  You can’t use interrupts in the bootloader, because the interrupt vectors are near the reset vector $0000, and will cause you to haphazardly enter certain routines in the main program.  Bad news bears.

$timeout = 200000                          'we use a timeout

Bretries = 5                               'we try 5 times
Bstatus = Waitkey(#1)                      'wait for the loader to send a byte

Print #1 , Chr(bstatus);                   'return the received byte to confirm reception

If Bstatus = 123 Then                      'did we received value 123 ?
  Bkind = 0                                'prepare to receive flash program
  Goto Loader
Elseif Bstatus = 124 Then                  ' EEPROM
  Bkind = 1                                ' prepare to receive EEPROM data
  Goto Loader
Elseif Bstatus <> 0 Then
  Decr Bretries
  If Bretries <> 0 Then Goto Testfor123    'we test again
End If

For J = 1 To 10                            'blink LED to indicate start of normal program
 Toggle Portb.2 : Waitms 100

Goto _reset                                'goto the normal reset vector at address 0

There’s a string or two of spaghetti code in there, but it’s pretty straightforward.  We’re going to try to get a byte 5 times (Bretries).  Each time we check, we’re going to call Waitkey(#1), which is blocking code.  It won’t go any further until it either receives a byte, or the timeout is reached.  You’ve also probably noticed that this bootloader program will accept EEPROM data, I won’t dive into that either but it’s not hard to figure out.

If it got the correct byte to expect flash program data (decimal value 123, also the ASCII character “{“), then it will jump to the “Loader:” label, and begin XModem reception.

If it didn’t get the right byte, then it retries.  After five retries, it blinks an led 5 times quickly to let the user know that the normal program is starting, and then jumps to the reset vector.

BASCOM has an internal programming option that lets you transmit the binary file via the bootloader directly from the IDE.  However, you can use other terminal emulators (such as HyperTerminal) to send the “{” character, wait for the response, and then use the “Send File” menu option.  After running into some trouble using Linux terminal emulators to communicate with the bootloader (I’m not sure why, has to do with lrzsz…), I wrote a C program (that I will soon add to the repository) that can be called from a Makefile to send the program as well.

You could make the bootloader initiation signal be something other than a character coming over the UART: a button held down at startup, another serial signal, or even read an EEPROM value.

Another cool way to use the bootloader is to call it from the main program.  Since we know the address of our bootloader, we could put a bootloader menu option in the main program.  When selected, all we have to do is jump from normal main program flow to the bootloader program location $FC00.  This is pretty handy, too, because then you don’t even have to power cycle to reload your program!

Hopefully this sheds some light onto how bootloaders work, and why they’re so nice.  As I always say, if you have the chance to choose between regular heaven and bootloader heaven, choose bootloader heaven.  It may be a joke, but if not, mmmm boy!

Categories: General

ZephyrEye: Rev1 vs Rev2

11 February 2010 7 comments

OK folks, I’ve received quite a few requests so here’s what’s up with the circuit boards I have available.  They are Revision 1, and have some hardware bugs (all of which can be corrected with a scalpel, soldering iron, and a fair amount of skill).  I’d like to go through the rundown once here so everyone understands what’s up.

The plan is to get started with Revision 2 soon.  There are quite a few feature improvements that would make the ZephyrEye work a lot better, and I’d like to list them.  I’m not trying to talk anyone out of a Rev1 board, I will gladly send them (without charge but unpopulated) to anyone until I run out, but I would like to avoid anyone having false expectations of what it can do.  That being said, it will probably be at least a few months before Revision 2 is ready.

If you are thinking about building a ZephyrEye, please use this post to consider your options.  Remember, it really can’t do much of anything by itself – it only tracks other ZephyrEyes, so think in pairs.  And Rev2 is very unlikely to be backwards compatible with Rev1.

Revision 1

I feel kind of like I’m hanging out my dirty laundry, these are some pretty silly mistakes:

  • LCD connector is missing two traces, which requires hand soldering wires to this connector.
  • Traces ran too close under the LCD connector, so installing the connector requires bending the pins down at an angle and soldering them without the connector having full flush contact with the board.  This bug proudly brought to you by the autorouter.
  • An extra voltage regulator needs to get patched in for the XBee, which outdid the current supply capabilities of the original regulator.

Hardware that is still untested:

  • Microphone to ADC
  • ADC channel for voltage monitoring
  • Charging indicator from LiPoly chip

State of Software:

  • Has a bootloader for easy, wireless program updates
  • Can do simple system setup
  • Can play King of the Hill, but currently limited to 2 players (I currently only have two ZephyrEyes to play with ;)
  • Still has a few bugs, graphic artifacts, etc.
  • Still needs other games programmed into it.

I only have unpopulated circuit boards (e.g., bare as the day they were born), so it’s up to you to have the tools, AVR programmer, XBees, GPS module, and pretty much every other part if you are considering putting one of these together.  Alternately, if enough people request it and are interested, I might put together some kits.  Email me or leave a comment if interested.

Revision 2

On top of the features Revision 1 already has, I would like to add the following features.  Note that some of these are crucial to be successful in playing paintball with a ZephyrEye.

  • Clear epoxy filled case that can take direct paintball impact and other abuse
  • Capacitive touch buttons, which would enable the above feature.  These would replace the tact switch buttons for the menu, zoom, and power buttons.
  • Digital compass for heading compensation.  This way the “radar” is oriented the direction you’re facing, rather than just pointing north, which is a little confusing if you aren’t a well-oriented person.
  • Helical GPS antenna, for better reception when near other objects (like your arm, body, or hopper)
  • GPS module (or chipset) with higher sensitivity and output frequency (> 1Hz)
  • Swap out the Series 1 XBee for either a 900MHz XBee or a MeshNetics ZigBit module, which have longer range and more complete, ZigBee compliant firmware.
  • If possible, an optional external ZigBee antenna for better transmissions in, say, densely forested or urban arenas.
  • Use the newer, faster XMega256.  More peripherals, and runs at a blazing 32MHz.  She’s fast enough for you, old man.

Make sure and post comments here or join the Google Code project if you’d like to have input on what Version 2 will be able to do.

Edit: I’ve also just created a Google Group for project development discussions.  If you think you’d ever be interested in using a ZephyrEye, for paintball or other, please join the group and put your thoughts up.  Revision 2 hardware development will begin in earnest soon, so now is the time to ask for features.  I’m torn between adding a can-opener or laser pointer … surely your ideas are better.

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 .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
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 BC108B BC108B Q1
1 EM408 EM408 GPS
1 MAX1555 MAX1555 MAX1555
1 MEGA128-A MEGA128-A IC1
1 TPS61040 TPS61040 VR_LCD

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
   Snd_data 0
   Snd_data 2
   Snd_data 4
   Snd_data 6
   Snd_data 8
   Snd_data 10
   Snd_data 12
   Snd_data 15
   Snd_data 0
   Snd_data 2
   Snd_data 4
   Snd_data 6
   Snd_data 8
   Snd_data 10
   Snd_data 12
   Snd_data 15
   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 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!