I got on a few weeks back to create a new post, and found that my website was gone! Instead I just got a browser error saying I had too many redirects. I hoped maybe there was just a problem with the server, but it turns out the site had been hacked.

I host my site with Dreamhost, and I’ve always been very pleased with their terms, resources, and service. This was no exception. I submitted a help request and a very friendly robot got back to me in a couple days. (I indicated on the ticket that it wasn’t very important, otherwise I think it would have been sooner). The automatic scan found that I had several files with improper permissions, including one that was set to full read and write access for anyone on the server! The robot automatically cleaned that one up, and suggested I change the permissions of some other files.

Fortunately the “hacker” wasn’t a person with malicious intent, or I probably would have had unrecoverable damage. Instead it was just some rampant script. I hadn’t ever thought about it, but once a script or other malware gets on a site on the same server, improper permissions make it very easy for it to propagate to other sites. It looks like the damage was in the many Apache .htaccess files that the script littered everywhere, overwriting any that WordPress or I put in place. I removed these, but didn’t want to leave anything to chance, so I rebuilt everything.

Dreamhost has an excellent wiki page to help if you get hacked, describing how to set everything up again with a minimum of hassle. After some work, everything was restored. I was a bit sad that I couldn’t find my old theme, but everything else is back in place. (More on the theme later).

For anyone running web services on a unix server, the venerable ‘find’ utility has the ability to find files based on permissions. The following search will find any files or directories that have improper permissions:

find . -type d -perm /022 -o -type f -perm /133

This finds any directories with permissions greater than 755 or files with permissions greater than 644. In scanning, I’ve noticed that things I’ve unzipped seem to have unnecessarily high permissions, so watch out for zip archives, or anything copied from a Windows machine. I also noticed that when uploading by FTP, the upload log shows that the permissions are changed for the uploaded files, which must be a setting on the server. I had previously deployed using tarballs, but I think I’ll be making more use of an FTP client in the future.

It was a bit of a nuisance, but I learned something and got the kick I needed to get me to update the site a bit.

Posted in Linux, security, web | Comments Off on Hacked!

A Journey into Optimization

At work, I am developing for a Coldfire V1 processor using Freescale’s Codewarrior development environment. Sometimes when digging into the generated assembly, I notice that the compiler seems to have made strange choices about register use and stack management. I mentioned one particularly strange sequence to a friend, who asked about the optimization settings of the compiler. He said that the unoptimized actions of the compiler are very mechanical. To use a variable in a function, it is read from the stack, changed, and written back to the stack. If it’s used again, it will be read back from the stack and written again when it’s done. He mentioned that register coloring is used to improve this behavior by keeping values in registers instead of always syncing them to memory. I didn’t know much about optimization, so I looked into it.

I went back and looked at some code that the compiler should be able to optimize down to a single bit set. The code is here, but you can take my word for it that all this is doing is setting a bit:

#define SCG_BASE                        (0xFFFF8108)

#define SCG_REG                         ((u8 *)SCG_BASE)
#define CLOCK_REG_IDX(num)              ((num) >> 3)
#define CLOCK_BIT_NUM(num)              (1 << ((num) & 0x07))

#define CLOCK_ENABLE(num)               (SCG_REG[CLOCK_REG_IDX(num)] \
                                              |= CLOCK_BIT_NUM(num))

This code allows me to enumerate a list of clocks in a particular order, then turn them on using just their enumerated values. The macros allow this to be resolved at compile time to a known bit set at an absolute address.

When run with no optimiation, the compiler generated this:

0x0000B0F6  0x717C8109               mvs.w    #-32503,d0
0x0000B0FA  0x2D40FF6C               move.l   d0,-148(a6)
0x0000B0FE  0x226EFF6C               movea.l  -148(a6),a1
0x0000B102  0x206EFF6C               movea.l  -148(a6),a0
0x0000B106  0x1010                   move.b   (a0),d0
0x0000B108  0x08C00002               bset     #2,d0
0x0000B10C  0x1280                   move.b   d0,(a1)

A quick coldfire assembly primer: d0-d7 are general purpose data registers, a0-a7 are general purpose address registers, and the parentheses around a register is an indexed operation. (a0) uses the value pointed to by the address in a0, and -148(a6) reads the value located 148 bytes below the address stored in a6. In a move operation, the source is first and the destination second. a6 is a stack frame pointer.

So the absolute address that we want to modify is loaded into d0 and transferred onto the stack. The value is then loaded from the stack into a0 and a1. The current value at this address is loaded into d0, the bit is set, and the value is written back to the address. The compiler doesn't even trust itself to not destroy the address between reading and writing, so it loads it into both a0 and a1 and uses one for the read and the other for the write. This is hardly the efficiency I was hoping for, but the compiler can't really be blamed for this when optimizations are completely off.

Here is the assembly generated with optimization set at 2:

;  932:     
0x0000A046  0x717C8109               mvs.w    #-32503,d0
0x0000A04A  0x2D40FF6C               move.l   d0,-148(a6)
0x0000A04E  0x2240                   movea.l  d0,a1
0x0000A050  0x2040                   movea.l  d0,a0
0x0000A052  0x1010                   move.b   (a0),d0
0x0000A054  0x08C00002               bset     #2,d0
0x0000A058  0x1280                   move.b   d0,(a1)

Hmph. Not exactly a stellar attempt at optimization. I am used to GCC, where an optimiation level of 2 is a collection of optimizations that are applied. It's an easy way to say "I want some optimization, but let's not go crazy." To the Freescale compiler it apparently means "Take the day off."

However, my friend had mentioned register coloring. I had seen a setting mentioning this before and went to find it. Strangely, this is not in the same place in the IDE as the optimizations, but I found it and saw it was turned off. After turning it on, here's what I got:

;  932:     
0x0000839E  0x717C8109               mvs.w    #-32503,d0
0x000083A2  0x2040                   movea.l  d0,a0
0x000083A4  0x1010                   move.b   (a0),d0
0x000083A6  0x08C00002               bset     #2,d0
0x000083AA  0x1080                   move.b   d0,(a0)

OK, better! The spark has sizzled out of our love affair with the stack, and we can keep the values in registers. Also, we know that we're not trashing a0 and can use it again later when we store the value back.

On the same page as the register coloring I also saw peephole optimization, which is an optimization pass that tries to use specific instructions/features of the target processor to improve performance. This sounds like something else I'd be interested in. Here is level 2 optimization with coloring and peepholes:

;  932:     
0x00007EAE  0xA540                   mov3q    #2,d0
0x00007EB0  0x01F88109               bset     d0,0xffff8109

Great! It's almost like we know what we're doing here. We load the number of the bit we want set into a register, then call the bitset operation. The only thing better would be to use an immediate value for the bit to set to avoid loading it first. I tried to write the assembly myself to specify an immediate value to the bset operation:

bset      #2,0xffff8109

But this doesn't assemble. It looks like the hardware doesn't support this addressing mode. So the result from the O2, coloring, peephole settings is the best we could do!

This was a particularly useful find for me, as I had briefly tried optimization on this compiler before and decided it wasn't very useful. I was starting to worry about the total size of my application, so I turned on O2. The results were basically meaningless, which isn't a surprise after seeing what O2 did in the above example. The size of my current complete binary with O0 is about 110K. With O2 but no coloring or peephole, it is about 100K. However, O2 with coloring and peephole is about 81K, which is a great improvement.

Posted in Uncategorized | Comments Off on A Journey into Optimization

Install CyanogenMod on LG G2x

I have wanted to try CyanogenMod on my G2x for a while, and finally decided to go for it. I tried to follow the rooting instructions on the CyanogenMod wiki, but they didn’t work for my version of Android (2.3). Most of the forum posts for help with these issues involve links to script-kiddie-like tools for rooting phones from Windows, which were completely unhelpful. I did finally find a site with reasonable instructions, but even that was a collection of links to various terse forum posts. All of the back-and-forth between similar looking lists of instructions creates a lot of confusion, which is not what you want when trying to do something carefully.

I finally got everything running excellently on my phone and am really happy with CyanogenMod. However, in the confusion, I forgot a step (SMS backup) and didn’t perform another step, so I lost my messages and some podcast audio, but those are not a big deal for me.

For myself and anyone else interested in trying, I’m documenting the instructions that I would follow next time if I were doing this again (including the steps I missed). I don’t have much experience with this, so take it for what it’s worth. These instructions are for Linux, but the link above has similar instructions for Windows, if you prefer.

I obviously can’t guarantee the results on your device. Be aware that this procedure voids your warranty. You are responsible for any damage to your device or loss of your data. These instructions are only for the G2x running Android version 2.3.3. Do not attempt them on any other phone.

Rooting your G2x
(If you already have a rooted phone, skip this section, and proceed to Backing up your data).
Android has a section of it’s memory reserved for performing system maintenance and recovery called the recovery partition. The first step is to replace your default recovery partition with a tool (ClockworkMod) that will help you install custom firmware. [Source] I’m pretty sure that this step is unnecessary, as I think the next step just overwrites it. I’ve included the directions that I followed though, because I’m not sure.

  1. Download http://mirror.dal.tdrevolution.net/ctso/g2x/nvflash-recovery.tgz to your PC.
  2. Power off your phone normally.
  3. Remove the battery from your phone.
  4. In a terminal, run ‘lsusb’ to see your USB devices before connecting the phone.
  5. With the battery still out, hold down both the volume up and volume down buttons, and connect the USB cable to your phone and PC. After connecting, wait for a few seconds, then release the buttons. There will be no response from the phone.
  6. Run ‘lsusb’ again. You should see a new device listed, which is the phone. For me this was
    Bus 002 Device 015: ID 0955:7f20 NVidia Corp.

  7. On your PC, make a new directory (e.g. “nvflash”) and extract the contents of the first download into it:
    mkdir nvflash
    tar -xaf nvflash-recovery.tgz -C nvflash

    Change into the extraction directory and run the ./flash-recovery.sh script. For me the script returned an error, after copying the file, but this is ok. You want to see:
    / 1024992/1024992 bytes sent
    fastboot.bin sent successfully

  8. Disconnect USB from the phone.

The next step is to update to ClockworkMod tool, using a similar procedure. [Source]

  1. Download http://krylon360.com/file_host/G2x/nvflash-internal-08222011.zip to your PC.
  2. Remove the battery from your phone.
  3. In a terminal, run ‘lsusb’ to see your USB devices before connecting the phone.
  4. With the battery still out, hold down both the volume up and volume down buttons, and connect the USB cable to your phone and PC. After connecting, wait for a few seconds, then release the buttons. There will be no response from the phone.
  5. Run ‘lsusb’ again. You should see the phone listed.
  6. Create a second directory and extract the contents of the second download into it.
    mkdir ClockworkMod
    mv nvflash-internal-08222011.zip ClockworkMod
    cd ClockworkMod
    unzip nvflash-internal-08222011.zip

  7. Run ./flash-recovery.sh from the second directory. This one should complete successfully.
  8. Disconnect USB from the phone.

The final step is to use ClockworkMod to root the phone. [Source]

  1. Download the G2x root zip to your PC: http://www.mediafire.com/?92qpr525ztblh8w
  2. Copy the zip file (do not extract) to your phone SD card. (When I mount my phone over USB Mass Storage, I see two devices. I copied to to both just to not have to repeat the procedure).
  3. Turn off the phone normally.
  4. Hold down the volume down button, then press and hold the power button until the second screen (Android with apple) appears, then release both buttons. You are now in ClockworkMod. You can move through the menus with volume up and volume down. Select menu items with the power button.
  5. Select “Install zip from sd card”.
  6. Select the root zip file.
  7. Return the the main menu and select reboot phone. The phone will be rooted on reboot.

Backing up your data

  1. First, backup all your application data. Connect your phone to your PC and activate USB Mass Storage. Copy all of the data off of the volumes that mount. This will all be erased in the update.
  2. Download “Titanium Backup” and “SMS Backup & Restore” from the Android Market.
  3. Run Titanium Backup. It will sometimes complain about your phone settings. You need to have Unknown Sources selected (Settings->Applications->Unknown Sources) and USB Debugging selected (Settings->Applications->Development->USB Debugging). I kept getting an error about USB debugging until I disconnected USB from the PC. Once you get no errors on startup, continue to the next step.
  4. From the context menu select Preferences->Backup Folder Location. The default should be something like /mnt/sdcard/TitaniumBackup. Press “Use the Current Folder”. (Backups do not seem to work until you go in and verify the directory). Press “Back” to leave the preferences menu.
  5. The next step will perform a backup. My backup was about 180 Megs, but I don’t have a lot of applications. You may want to make sure you have 300 – 500 megs free on your SD card before starting. Since you just backed up your application data to the PC, you can delete some of this to make room.
  6. From the context menu, select “Batch”.
  7. Under the “Backup” section, you should see a non-zero number beside “Backup all user apps + system data”. If not, go fix the backup directory. If you do see a number, press the run button next to this option. The backup should run for a few minutes. If it is nearly intantaneous, something went wrong… try again.
  8. Exit Titanium Backup.
  9. Run SMS Backup and Restore. (I forgot this part when I was doing my install, but it’s not complicated. This should work).
  10. Press “Backup”. Select a file name (default should be fine). You should see a screen showing a non-zero number of “Successful” backups.
  11. Exit SMS Backup and Restore.
  12. Mount USB mass storage to your PC. (You will need to turn off USB Debugging for this to work).
  13. Copy the TitaniumBackup folder to your PC. Make sure that this has lots of files named like your applications.
  14. Copy the SMSBackupRestore folder to your PC. Make sure that this contains the file you created when you backed up SMS.
  15. Now perform any other backup steps you can think of. Sync your contacts and other info with your Google account. E-mail important information to yourself. If there’s anything you don’t want to lose, find a way to back it up somehow. There’s no going back.

Install CyanogenMod
From here on in, you can follow the instructions on the CyanogenMod Wiki page for G2x, but I’ll summarize them quickly here. Be careful to make a backup of your current install if you want it. They list this as kind of a sub-option of their “Boot into ClockworkMod” step which makes it easy to miss.

  1. Download the latest version of CyanogenMod for G2x
  2. Download the Google Apps package
  3. Copy both files to the root of the SD card
  4. Boot into ClockworkMod as before
  5. Select Backup and Restore
  6. Select “Wipe data/factory reset”
  7. Select “Wipe cache partition”
  8. Select “Install from SDCard”
  9. Select “Choose zip from SDCard”
  10. Select the CyanogenMod update file.
  11. Select “Install from SDCard”
  12. Select “Choose zip from SDCard”
  13. Select the Google Apps file.
  14. Go back to the main menu and select “Reboot system”.

Congratulations! You’re now running CyanogenMod!

To get back all your awesome stuff:

  1. In the Android setup, don’t bother to associate your Google account yet. It will try to download your apps, which wastes your bandwidth and time since Titanium already did this for you.
  2. Download Titanium Backup and SMS Backup and Restore from the Market.
  3. Mount your device over USB Mass storage, and replace the empty TitaniumBackup and SMSRestoreBackup folders with the ones you copied to your PC.
  4. Run Titanium Backup. Select the Backup Directory as before. Under Batch->Restore, you should see a non-zero number beside “Restore missing apps + all system data”. Select “Run” beside this option. I had to manually confirm the install of a lot of apps.
  5. Run SMS Restore and Backup. Select “Restore”, then select the file that you backed up to.
  6. Copy any photos or anything else not preserved across the update back to the phone.

You should be good to go!

Posted in Android, Linux | 2 Comments

CanShield Software Update

I’ve been poking around with the CanShield software recently to try to clean it up. I felt that the first release was a bit cumbersome to use and had some maintenance disadvantages for me. As I’ve been considering adding features, I’ve found it hard to see how to integrate them into the current setup. I’ve fixed it up some and have posted a new release, 1.10.

The initialization and cleanup are still the same, CAN.begin() and CAN.end(). The mode is still set with CAN.setMode(), and you can still check whether a message has been received with CAN.available(). However, this is about the end of the similarities.

I thought that the message handling was cumbersome, having to make a separate call to retrieve the message ID and the data. If you’re signalling with message IDs only (no data), it’s weird to have to mark the message as received, since you don’t have to when you retrieve data.

To fix this, there is now a message object. For those unfamiliar with the concept, an object is like a variable that contains other variables. In this case, there is a CanMessage object, which contains the ID, data, data length, and a variable to mark whether the message has an extended identifier. It is no different than having several normal variables, except that the whole bundle can be passed around together. When all this data is contained together in one object, it is easier to manage messages as a whole.

To create a message object, you declare it like any other variable:

CanMessage myMessage;

You can directly edit the variables inside of it by using the dot syntax, just like when you use different Arduino libraries. This sets the value of the variable inside the object, just like any other variable:

myMessage.id = 1234;

Objects also have functions associated with them that can manipulate the data that they can contain. These functions are also called using the dot syntax. For the CanMessage object, data is set and messages are sent using object functions. (Functions associated with an object are sometimes called “methods”. For simplicity, I’ll stick with “functions”.) The following will set a byte of data into the CAN message field, then send the message:


The length field is automatically updated when any of the set-data functions are called.

To retrieve a message, you can call CAN.getMessage(). This returns a CanMessage:

myMessage = CAN.getMessage();

You can then read out the id and data:

id = myMessage.id;
data = myMessage.getByteFromData();

If you have a few different messages that you send for your application, you can declare them once, then update their fields and send them as needed.

CanMessage message1;
CanMessage message2;
CanMessage message3;

byte val1;
int val2;
long val3;

setup ()
message1.id = 1001;
message2.id = 1002;
message3.id = 1003;

loop ()
val1 = readSensor1 ();

val2 = readSensor2 ();

val3 = readSensor3 ();


At the beginning, I mentioned that this new scheme has maintenance advantages, too. I have changed the underlying structure of the library to use an MCP2515 library written in C. This is easier for me, as I develop in C. This way there is much less work in porting updates back to the Arduino environment. If anyone is writing their own C code for the Arduino board or AVR in general, it should be easy for them to use the MCP2515 and SPI implementations included in the CAN library with little or no change.

Please let me know what you think about these changes. I hope this makes the library easier to use. If you have suggestions for improvements, please send them along!

Posted in CAN, Electronics, Programming | 2 Comments

Laptop Teardown and Cleanup

Over five years ago, I bought a Dell Inspiron 6000 laptop. I love this laptop. It has a non-shiny screen, 1680×1050 resolution (larger than more recent Dell models), well functioning trackpad, sturdy construction… it’s just an all-around great machine. It is still my main computer for everything other than games. I run Ubuntu on it, and it can handle anything I want it to do just fine.

Over the past year or two, I have noticed more and more that it seems to heat up quickly. After about 15-20 minutes or regular use (or 30 seconds of flash video) the fan would be going full blast, crying for help. I knew that dust was building up inside, and I’ve meant for a while to take it apart and give it the cleaning that it needed. So last weekend, I finally sat down to do it.

Unfortunately, to get to the fan, you pretty much have to take the whole thing apart. Fortunately, Dell has made this pretty easy. They have very clear instructions with pictures detailing each step of the process. The plastic covers seem designed to come off without excessive force. I didn’t have a problem with breaking the plastic connectors, and the paneling all seemed to snap back into place nicely. The screws that need to be removed are all phillips-head and not something like torx bits that the average household doesn’t have. In fact, the screw heads were helpful, because a screw that I at first thought I was supposed to remove had a hex-head. This seemed strange since all the others were phillips. After a bit more looking around, I found a different phillips-head screw, which was the one that I was actually supposed to remove. The connectors are all easily accessible and can be removed and re-connected without trouble. Why can’t more consumer products be like this?

Here’s a picture of the laptop after tear-down:
Dell 6000 Teardown

I was saddened to see the state that the fan was in:
Dusty Laptop Fan

A solid layer of insulating dust had formed between the heatsink and the fan. No wonder this guy was getting hot! I removed it and carefully cleaned inside and out. After a little love, it looked much better:
Clean Laptop Fan

Reassembly was as easy as teardown, except I got a little hasty and forgot to reconnect the touchpad connector. (Oops!) Since I cleaned it out, I haven’t heard the fan kick up to that high speed, even after a few hours of use (or several minutes of flash video). Of course this probably isn’t shocking news to anyone, but I wanted to post up some encouragement to anyone considering a home repair. The dust probably needs to be cleaned out of laptops every year or so, and it’s a fun feeling of accomplishment to do simple maintenance on the things you own. I would have done this months ago if I’d have known that it would have been this quick and easy. I hope this gives my laptop another five years of life.

Of course, it’s not always so easy…

(This video is Jayme Gutierrez’s brilliance, not mine)

Post up in the comments your experience with laptop or other electronics maintenance!

Posted in Uncategorized | Comments Off on Laptop Teardown and Cleanup

Fridge Door Alarm – 555 Contest Entry

This is my submission for the 555 contest. It is a door alarm, intended to notify you when you have left your refrigerator door open. It’s a project that I’ve had in the back of my mind for a while that I intended to use a microcontroller for. However, when I saw the 555 contest, I realized that it could be done very simply with a couple of timers!

The project has two parts, a sender and a receiver. The sender sends pulses of IR light at fixed intervals. The receiver counts the time since the last pulse was received, restarting its count when a new pulse is received. When the receiver timer expires, it sounds an alarm to notify the user that the door has been left open. While this project is built for refrigerator doors, the circuit will also work for other beam-break alarm applications.


The receiver is housed in an Altoids mint tin with a small hole poked in the side. The phototransistor inside is aligned with the hole, but set back a little in the case. For IR light to interact with the phototransistor, the source must be almost directly in line with the hole and the diode. This allows the system to detect even a small offset of the sender. It also reduces the chances of triggering due to ambient IR light. The Altoids tin is ferrous, making it easy to hold to the fridge with a couple of magnets, no adhesive required.

The sender does not need an enclosure, but one could be added for aesthetics. A piece of double-adhesive foam holds it onto a magnet.

Technical details

The 555 timer in the sender unit is configured as an astable timer, generating a fixed-duty-cycle waveform. This is used to generate pulses from the IR diode. The project would also work if the IR diode were on constantly, but this is a waste of power. Powering the diode intermittently greatly increases battery life. Since fewer components are required to generate a waveform with a duty cycle greater than 50%, the timer output is connected to the cathode of the LED, powering it during the low portion of the waveform. In my design I used a duty cycle of about 90%, so the diode is only on 10% of the time.

Sender Schematic

Sender Schematic

The timer in the receiver unit is configured as a monostable or one-shot timer. The time interval is determined by the resistor and capacitor connected to the discharge and threshold pins. The time needs to be on the order of seconds or tens of seconds, requiring a high RC value. To be power efficient, we want to use a small capacitor, so a very large resistor is used to cause a long delay. Multiple resistors could be used in series here to create a longer delay.

Receiver Schematic

Receiver Schematic

The phototransistor in the receiver is an NPN transistor with its emitter connected to ground. The collector is pulled up with a 10K resistor, creating a normally high pulse signal. When an IR pulse is received, the transistor conducts, pulling the pulse signal to ground. Unfortunately for this application, a trigger pulse that occurs while the timer is running does not restart the timer. Instead, we have to manually reset and retrigger the timer.

The pulse signal is connected directly to the reset pin so that a received pulse ends the currently active timer interval. After the reset, the timer needs to be retriggered. The pulse signal is connected to the trigger through an RC network to delay the signal slightly. This causes the trigger to stay low longer than the reset signal, triggering the next timer interval. Finally, to keep the output from dropping and triggering the speaker during the pulse interval, the pulse signal activates a transistor to pull the output high during the reset period.

When no pulses have been received for the complete timer interval, the output drops to 0 volts. With no pulse signal, the PNP transistor is not conducting, and the 555 output pin grounds the negative side of the speaker, setting off the alarm. Hey! Close the door!

Posted in Electronics | Tagged , | 3 Comments

CAN Shield Kits and Software

After a busy holiday season, I finally got around to finishing up the CAN Shield software and putting together the kits. The kits are now available in the products section! I’ve also uploaded the first release of the CAN Shield Arduino library at the FazJaxton GitHub. This is designed for the CAN Shield, but should work with any MCP2515-based CAN setup. I have a few improvements planned for it, but I’m pretty pleased with the first release. Please let me know what you think!

Posted in CAN, PCB, Programming, Uncategorized | Comments Off on CAN Shield Kits and Software

Can Shield Assembled

Can Shield Populated

It works!

Posted in CAN, PCB | 4 Comments

Boards Are In!

Can Shield Boards

The CAN boards have arrived from Gold Phoenix!  The turnaround time was amazing.  I was quoted a five day lead time, plus shipping time.  I fully expected to wait at least two weeks for manufactuing and shipping.  Yet here they are in my posession a week after I placed the order!

They look great!  It’s really cool to hold a real physical board that I designed.  The quality seems to be really good, too.  There are a few places where the silk screen is just a bit smudged, but the solder, routing, drilling, and everything else are just as expected.  So cool!  I’m going to get one put together ASAP.

Posted in CAN, PCB | Comments Off on Boards Are In!

SparkFun CAN Shield

After all my work on the CAN shield, I opened up my RSS reader this morning, and saw that SparkFun beat me to it! One of SparkFun’s newest products is a CAN shield of their own. It looks like a good product, with lots of features for integrating into a car. I’m a fan of SparkFun, and I’m glad that other people are interested in CAN, too.

I’m not worried about some competition. The SparkFun product and the kit that I am putting together are different for several reasons. First, SparkFun’s product is not a kit. It’s a pre-assembled, surface-mount board. Mine will be a through-hole kit that you put together yourself. Second, SparkFun’s kit is very specifically for use in cars, with only one connector for this purpose. I have added options for a few types of connectors with customizable pinouts to make this shield useful in lots of applications, not just automotive. SparkFun’s kit has support for all types of accessories, such as an SD card, GPS, and an LCD screen. My kit will be just for CAN. Finally, my kit should be significantly cheaper than the SparkFun shield. I don’t want to commit to a final price just yet, but it’s looking like it will be about half the cost of the SparkFun shield. I think both products will find their niche.

Kudos to SparkFun for adding another cool product!

Posted in CAN | Comments Off on SparkFun CAN Shield