Building an OBD Speed Pulse: Behold the ICE

I am a crappy software coder when it comes down to it. I didn’t pay attention when everything went object oriented and my roots were always assembly language and Real Time Operating Systems (RTOS) anyways.

So it only natural that I would reach for a true In-Circuit-Emulator (ICE) to finish of my little OBDII bus to speed pulse generator widget. ICE is a hardware device used to debug embedded systems. It communicates with the microcontroller on your board, allowing you to view what is going on by pausing execution and inspecting or changing values in the hardware registers. If you want to be great at embedded development you need to be great at using in-circuit emulation.

Not only do I get to watch my mistakes in near real time, I get to make a video about it.

Getting Data Out of a Vehicle

I’ve been working on a small board which will plug into my car and give direct access to speed reported on the Controller Area Network (CAN bus).

To back up a bit, my last video post was about my inane desire to make a small assembly that could plug into the OBDII port on my truck and create a series of pulses representing the speed of the vehicle for my GPS to function much more accurately. While there was a wire buried deep in the multiple bundles of wires connected to the vehicle’s Engine Control Module, I have decided for numerous reasons to create my own signal source.

At the heart of my project is the need to convert the OBDII port and the underlying CAN protocol to a simple variable representing the speed, and to then covert that value to a pulse stream where the frequency varied based on speed. The OBDII/CAN Protocol is handled by the STN1110 chip and converted to ASCII, and I am using an ATmega328 like found on a multitude of Arduino’ish boards for the ASCII to pulse conversion. I’m using hardware interrupts to control the signal output for rock-solid, jitter-free timing.

Walk through the process of using an In-Circuit Emulator in the video below, and join me after the break for a few more details on the process.

The Hardware

I revised the board since the last video and removed the support for the various protocols other than CAN, which is the non-obsolete protocol of the bunch. By removing a bunch of parts I was able to change the package style to through-hole which is easier for many home hobbyists, so you can leave the solder-paste in the ‘fridge.

The “Other Connector” on your Arduino

Unlike the Arduino which is ready to talk to your USB port when you take it out of the box, the ATmega chips arrive without any knowledge of how to go and download code, in other words it doesn’t have a boot loader. Consequently I have the In-Circuit-Serial-Programming (ICSP) pins routed to a pin header on my board so that I can program the part directly.

On this connector you’ll find the Reset line, which means with this header I can use a true ICE utilizing the debugWIRE protocol. Since the vast majority of designs that use an AVR chip do not repurpose the reset pin for GPIO, it is a perfect pin to use for ICE. All of the communications during the debug process will take place on the reset pin.

Enter the ICE

When designing a computer from scratch there is always the stage where nothing yet works. Simply put, a microprocessor circuit cannot work until almost every part of the design works; RAM, ROM, and the underlying buses all need to (mostly) work before simple things can be done. As a hardware engineer by trade I would always reach for an ICE to kick off the implementation; only after the Beta release would the ICE start to gather dust in the corner.

In the case of the ATmega, the debugging capabilities are built into the microcontroller itself. This is a much more straightforward implementation than the early days when we had to have a second isolated processor running off-board with its own local RAM/ROM.

One note mentioned in the video is that a standard Arduino’ish board needs to have the filter capacitors removed from the RESET line to allow the high speed data on the line for its debugWIRE usage.

The ICE I am using here is the one made by Atmel, and is compatible with Atmel Studio, there are also other models available such as the AVR Dragon.


The ICE allows us to download and single step our code while being able to observe and overwrite RAM and I/O Registers from the keyboard. We are able to watch the program step by step or look underneath at the actual assembly code generated by the compiler. We can watch variables and locations directly in RAM or watch the C language counterparts. It’s also possible to jump over a sub-routine call in the instance of just wanting to see the result without all of the processing.

It’s worth your time to see even a glimpse of the capabilities of an ICE in action. I recommend that you watch the video where the debugging begin.

Final Words

This video was really about finishing the OBDII circuit so I didn’t really have the time to go over everything an ICE can do, maybe I will do a post dedicated to just the ICE and development environment next time.

Read more from this series:
Bil Herd's Hackaday Originals

36 thoughts on “Building an OBD Speed Pulse: Behold the ICE

  1. You are not alone. I sometimes think that OO programming was invented by software profs just to confuse people, and to create a dark art out of a priori fairly easy subject :) I for one will stay with the old school procedural(?) programming, until the bitter end. GOSUB or death :)

    1. Funny, I interviewed last week for a firmware job, and was asked object oriented questions that I felt can’t out of left field… I know OO C++ works for embedded systems, but I’ve never had a great reason to use many of the concepts outside organizational reasons.

      1. There is definitely nothing wrong with applying OO concepts to embedded software, on a memory limited system you do have to worry about allocating too much memory dynamically but you would run into the same problem if you just allocated memory in C anyways. It’s nice to be able to instantiate 2 instances of a class to control two identical ADCs. It a heck of a lot cleaner then creating a whole bunch of variables and manually passing them by reference.

        I recently created a project with a heavily OO application front end written in C++ with Qt and C based firmware for a MCU so sometimes I do just write firmware in C anyways. At the end of the project I did feel that C++ would have made more sense for the firmware code.

    2. What is happening now is that the Object oriented languages have been taught for long enough that the people that only learned object oriented languages are now in management. As a result, more firmware jobs are requiring object oriented design, for better or worse. I lost out on what looked like a pretty nice job because I didn’t have C++ skills. Time to dust off the books and learn it.

      1. >people that only learned object oriented languages

        I’d expect those to be few and far between. At Florida Atlantic University, where I was both student and staff, every CompSci, CompEng, or EE student was required to take a microprocessors course that started with Assembly, then C, plus another course that required C++. From there, there were tons of electives that used OOP languages but every student had to at least learn the basics.

        It was hilarious watching freshmen gripe about having to write C for an MSP-430, when only a couple years prior I had taken the same course but with Assembly only and on ancient 68k trainer boards donated by Motorola in the 80’s.

        1. Virginia Tech used to require C++ on both Windows and *nix; they changed to Java for the first two years after moving CS from the Maths department to Engineering. The first year you were “encouraged” to avoid needless OO, but focused on pointers, references, pass-by-copy, etc. Second year introduced strong OO with templates, as you might design your own linked-list or K-d tree but never see the data type you were going to store. Other requirements were MIPS assembly, low level C for writing an OS, probably more I don’t remember. The only coders who learned only OO were the ones who left for a Business degree after the second year OO courses.

    3. You must be doing something wrong then. The whole point to OO is to simplify and abstract what’s going on under the hood.
      There are many bad class libraries out there (MFC anyone?), but when done well they allow you to plug code together like Lego, and test parts in isolation.
      This from someone who started programming in old fashioned BASIC and assembler, moved on to block structured coding and then OOP. Each step requires a change in thinking, but has distinct advantage over its predecessor.

      1. “Simplify and abstract” is great on a PC where processors are all virtually identical to the programmer. In order to meaningfully use a debugging tool at the embedded systems level and ensure maximal processor performance having a simple correspondence between high-level code and underlying assembly instructions is a requirement.

  2. OFFTOPIC: Do you know if it’s possible to tweak somehow the system that is responsible for the fuel consumption?
    I would love to contact you and chat on this topic.


    1. You mean tweak it the way Volkwagen did?
      A dozen or so years ago, there were a number of places you could get replacement chips for your car’s ECU or even tweak the parameters for more performance.
      Check out MegaSquirt they make ECU’s for hot rods, and they can be dialed in by their owners.

    2. There are third party products made that plug into you OBDII port but they have toms of research and then have been certified by CARB, etc (I believe). Its not easy to do, takes a full understanding of the close loop systems within the vehicle including the transmission settings, and then the mfg already has it dialed in pretty close. A lot f the third party actually dial in more performance rather than consumption.

      What John said below is accurate, its really about the driver’s habits, in fact some 3rd party widgets can be set to beep when wasting gas (basically watching the manifold pressure and some of the O2 sensors)

      1. Most of the “programmers” alter some portion the the driveability or engine operation that users won’t accept to increase some other option. Most are also not CARB approved. The days of just dumping more fuel are over.

      2. But thats not the hacker way is it Bill?, yes we will play with ‘tweaks’ we can, look at ultraguage device, atmega and a canbus, some tweaking of firmware and you got CAN to ‘anything’ , bluetooth or pi pick your poisen

      3. There are also third party products which do nothing more than blinking a LED to pretend they do anything. There are teardown videos of such fake devices on youtube, I think from bigclivedotcom.

    3. You can optimize fuel consumption, power and pollution – but not all three at the same time. The acceptable pollution value is not your own choice, so only two are left for a compromise, which is normally done acceptably by the car maker. So there is not much room for improvement when you are not allowed to increase pollution.

  3. I was convinced that OO programming was designed to be complicated so that geeks can earn more money. More likely, the folks inventing the languages were too close to the hardware to have good “real world” programming concepts. It is not that the principles of OO are inherently bad but, in many ways, OO languages are not really Object Oriented. A better term would be “class oriented” programming. May years ago, I spent some time trying to convince folks at Sun Labs that Java should be truly object oriented where behavior is associated with identifiable real world objects (you could call them “instances”). It is OK to have class behavior and inheritance but it is much better if you can dynamically assign an object to classes and have that assignment implicitly persist without needing to explicitly persist it using, say, database calls. Also, with inheritance, it becomes very important to establish a class structure that closely maps to the real world classification of objects. Such “real world” associations usually form a network and so hierarchical class structures are often artificial and limiting. There is much more to it that this but this should give a flavor of some of the issues with OO programming. In the meantime, while I wait for a real OO software environment (programming language is too limiting a term), I program using what is available.

    1. I agree, many originally procedural languages like PHP are adding what is called OOP by creating the class primitives but while that make look like an OOP it creates more problems than it solves. PHP only has one level of scope apart from the global scope so OOP doesn’t work as expected unless you also learn the scope controls necessary for it to do so and in that respect it’s NOT like a language that started as OOP.

      JavaScript is a good example of OOP as it’s tied to a Document Object Module (the web page) and inherently works better as OOP.

      For me OOP and procedural programming styles have their place but in every language that implements OOP with class structures like LUA for example, I just end up using procedural anyway.

      I think the bottom line is that with procedural languages you need to know what’s happening under the bonnet with things like scope while with OOP you just hope for the best.

      OOP is probably better for closed environment like micro-controller code where there are no, or limited, security attack vectors. In open environments like web servers, OOP creates a lot of security problems for beginners writing a platform.

      It’s sad the people aren’t learning procedural programming any more. OOP is better when there is a lot of functional duplication but an just about any other case, procedural is less effort.

  4. I wonder how hard it would be to make a tool that can do GM’s bidirectional protocols though I bet a lot of that is hidden behind NDAs and other BS screens.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s