Avoiding floating point on 8bit micros

For my recent project I need to measure two voltages with an ATmega8 and display them on a character LCD.
What’s the big deal?

When using a microcontroller to measure a voltage using a built-in ADC like in the ATmega8 then you will only get a digital representation of how many fractions of the reference voltage is present on the analog pin, not an absolute voltage reading in Volts (like you get from your multimeter).
There is nothing wrong with that if you only have to deal with these numbers in software where you can set thresholds or compare the magnitude of two voltages.

In this case I need to communicate with humans though, so it is desirable to display the actual voltage in Volts with digits after the decimal point. This is where we run into problems especially on small microcontrollers. Usually there is no fast way to deal with floating point numbers in 8bit micros. All the floating point calculation algorithms are software implementations which take up a lot of program memory and generally are pretty slow compared to integer math because they take many more cycles.

In my case I have found a very elegant solution to this problem, where by using simple arithmetic we can simplify the problem so that we only have to deal with displaying the decimal point after the correct digit rather than actually calculating floating point values.

Let’s start with an overview of what’s given (i.e. what we have to work with):

  • ADC resolution: 10 bits (1024 steps)
  • ADC reference voltage: 2.56V

The resolution of the ADC (i.e. how many volts one ADC count is) can be calculated like so:
c = \frac{V_{ref}}{2^{10}} = \frac{2.56V}{1024} = 2.5mV

The actual voltage at the input of the ADC for a given ADC reading k is:
V_{in} = k*c

Now by looking at this a bit closer we can see that 2.56V is actually a power of 2 once we multiply with 100, thus we can calculate the input voltage as follows:
100*V_{in} = k*100*\frac{2.56V}{1024} = \frac{k}{4}

Now why is this great?
Dividing by four can be done in a single instruction by right shifting the ADC reading by two bits.
Because we know that the reading divided by four is our input voltage times 100, we now simply have to make sure to display the decimal point in the correct place on the display. We never had to use floating point math to come to an exact decimal representation of the input voltage (the accuracy will still be limited by the absolute accuracy and temperature stability of the internal voltage reference of course).

Now this is only the beginning of the story.
Because I’m actually measuring voltages that are outside of the safe input voltage range of the ADC I have used voltage dividers to bring those voltages to appropriate levels.
I have to measure two voltages as follows:

  • V1: 0-20V fed into a 8:1 voltage divider, ADC input is 0-2.5V
  • V2: 0-3V fed into a 3:2.5 voltage divider, ADC input is 0-2.5V

Calculating V1

We can use the very general solution to the problem above and together with our voltage divider we can find a formula for calculating V1 from the ADC reading:
100*\frac{V_{1}}{8} = \frac{k}{4}
Multiplying by 8 simply yields:
100*V_{1} = 2k
Again we have reduced our problem to simply multiplying the ADC reading by two and making sure to display the decimal point at the correct digit.

uint16_t ADC_readPSUOutV(void)
	uint16_t temp;
	temp = ADC_readRaw(6);	// read from ADC channel 6 
	temp = temp<<1;			// multiply output by 2 
	return temp;

Calculating V2

The same works for V2:
100*\frac{V_{2}*2.5}{3} = \frac{k}{4}
Using simple arithmetic we find
1000*V_{2} = 3k
This result is even nicer because we can get a reading directly in millivolts just by multiplying the ADC reading by 3.

uint16_t ADC_readPSUOutI(void)
	uint16_t temp;
	temp = ADC_readRaw(7);	// read from ADC channel 7
	temp = temp * 3;
	return temp;


KiCAD tips

I have recently started a new project and I have learned a couple of new things about KiCAD’s pcbnew while laying out the PCB.

First of all I have to say that I am running a locally compiled version of KiCAD (BZR5464) on Linux Mint 17.1. Currently the only way to get a more recent build than the outdated BZR4022 stable build is to compile the source code yourself. I have found that the easiest way to do so on Linux is using the build script provided on the KiCAD Launchpad site.

This post is more of a random collection of things that I have found to make my life easier when using KiCAD. I may continue to edit this post to include more tips and tricks as I go using the newer versions of KiCAD.

I have also found that sometimes I just have to delete all sources before starting an update, otherwise the build will fail:

./kicad-install.sh --remove-sources
./kicad-install.sh --install-or-update

Another lesson I have learned is that you should never run this script as root. First of all because it generally is a bad idea to run everything as root and secondly because the script will place the global fp-lib-table file (the library configuration file) in your home directory. If you run the script as a normal user the owner of that file will be your user, running the script as root however will assign the created files the user root and group root which means that when running KiCAD you can’t edit the global library table because you are lacking permission to edit those files.
This can be fixed with

chown -R user:user ~./config/kicad

but it’s easier just to save yourself from the hassle.

I seemed to have a problem with my KiCAD build where the rendering in pcbnew was extremely slow. I didn’t really understand why rendering should be slow as my computer is not exactly low spec. After laying out the board I was told that the rendering/canvas mode can be changed to OpenGL (in the View menu or by hitting F11), which dramatically improves rendering speed on my machine.

Left side is standard rendering, on the right side OpenGL rendering
Left side is standard rendering, on the right side OpenGL rendering

A rendering feature that I find very useful is high contrast mode which can be activated by pressing the H key. What this does is that it only highlights/renders the currently selected layer in color. This is especially useful when laying out a PCB with components on both sides and having both layers displayed as overlaying eachother can make routing a bit confusing. It certainly made routing for me easier.

Left side high contrast mode, right side standard mode
Left side high contrast mode, right side standard mode

When exporting the Gerber files to submit to your PCB manufacturer, make sure that you check “Merge PTH and NPTH holes into one file” so that you don’t end up with two separate drill files just because your mounting holes may not be plated through hole (PTH).

I was surprised to see that the actual BOM generation doesn’t work anymore from within the schematic editor. It seems like the KiCAD devs have decided to use an XML netlist file and then generate a BOM from that using some external XML parser which you currenty have to set up yourself. I think that this is too much of a hassle for someone who just needs a BOM. It turns out that you can still export a regular BOM in CSV format out of the “Fabrication Outputs” menu in pcbnew.

Before submitting your gerbers to the fab make sure to go over this list of what you should have on your PCB: PCB Checklist – What to check before you submit.

And finally here are two resources for learning about KiCAD usage:

Why am I running Linux?

Today while sitting in a lecture one of the other students asked why I was running Linux on my laptop. To be honest I had a little trouble coming up with good reasons for why exactly I was running Linux almost exclusively nowadays. I had trouble coming up with some reasons not because I don’t have any but because I couldn’t immediately point out some whizbang feature that I use most.

“Why wouldn’t I want to use Linux?!”

Continue reading

Building a better antenna for ADS-B reception with RTL-SDR

Coming home for Christmas a couple of days ago I finally had access to my workbench again and built a better antenna for receiving ADS-B signals with the RTL-SDR dongle.


The antenna is a quarter wavelength ground plane. This type of antenna is surprisingly easy to build and massively improves my ADS-B reception. Currently the antenna is mounted onto the end of a 3m PVC pipe which holds it up in the corner of my room, effectively putting it 6 meters above the ground. Ideally it should be mounted outside but the current weather here in Germany doesn’t really make for a pleasant experience trying to mount an aerial.

Continue reading

Using the Raspberry Pi as an RTL-SDR streaming server

Do you have an unused Raspberry Pi lying around your bench somewhere and just can’t figure out what to do with it? You could build a wireless RTL-SDR streaming server!

Why would you want to do that? Well, maybe you’re in a similar situation like me and your computer is in a location where radio reception is very poor. This is where a small, WiFi connected RTL-SDR would be very handy, you can set it up in places where there is better radio reception and then stream the IQ data from the SDR to your PC for further processing.

My setup currenty looks like this:

In the picture you can see that I have a powered USB hub connecting the R820T based SDR and the TL-WN725N wireless stick to the Raspi. The antenna cable running off to the top is going to the antenna which is placed outside the window for better reception (the thick, steel reinforced walls in my apartment make it impossible to even tune in to local FM stations).

Continue reading

Getting into SDR

After seeing some videos of Alan Wolke, W2AEW building some software defined receiver kits and an episode of Hak5 where they track aircraft by decoding ADS-B signals my interest in RF applications, amateur radio and especially software defined receivers was spiked. Together with Michael Ossman’s great class on SDR with HackRF I finally decided to get myself one of those cheap RTL2832U based DVB-T dongles and have a go at it.


The installation of the needed software is pretty straightforward on Linux and on Windows.

Continue reading

Moving to Dresden to study Electronics Engineering

Over the next couple of days I will be moving into my new apartment in Dresden as I will be studying Electronics Engineering at the TUD.
Of course my dorm room is quite small so I can’t do any soldering and in general can’t have a work bench like I used to have in the basement at home. All the electronics work that involves soldering and more sophisticated debugging will be done at the Dresden hacker space Turmlabor which is conveniently only a short walk away from my apartment building.

Nonetheless I have taken a couple of dev boards and basic test and measurement equipment with me to be able to do some simple debugging work in my dorm room (which should be good enough for simple microcontroller work):

  • Rigol DS1102E 100MHz DSO
  • Uni-T UT61E DVM
  • ScanaPLUS logic analyzer
  • DangerousPrototypes BusBlaster JTAG interface
  • PICkit3 in circuit serial programmer & debugger
  • A couple of PIC18F dev boards
  • STM32F401RE-Nucleo
  • Texas Instruments Tiva-C Launchpad
  • Breadboard & jumper wires

I hope I’ll be able to do some more electronics work (and be motivated do so despite the fact I’ll study EE) once I’ve got everything figured out here in the new city.


Fixing ${KIGITHUB} issue in newer KiCAD builds

Today I was getting ready to associate some footprints in KiCAD for my SURV-Project and ran into issues with cvpcb.

KiCAD has been changing very rapidly since CERN announced that some of their people will be contributing to the project full time (nice to see OSS and OSHW support from CERN).

One of the new features is that the footprints (or modules as they call them) for KiCAD are now hosted on GitHub. I had some issues when starting up cvpcb complained about not being able to access the GitHub repositories for the library files.

A simple fix for this is adding this to your .bashrc:

export KIGITHUB='https://github.com/kicad'


Review of the IKALogic ScanaPLUS logic analyzer

Today I received a very useful tool which will certainly ease my work with programmable logic and digital buses, the IKALogic ScanaPLUS.

It is a 9-channel 100 MHz desktop logic analyzer which will cost you 199€ (about $275 US) and comes with a 2 year warranty. The multi platform (Windows, Mac, Linux) software associated with it is called ScanaStudio 2 and comes free of charge with many different protocol decoders.


Continue reading

Binary wrist watch guarantees being identified as a nerd

I have just finished my binary wrist watch project (well, the new revision anyway). I was surprised at how small I was able to make it compared to last time.

I chose to go with the “super-yellow” color LEDs as they fit the purple OSHpark PCB very nicely. The biggest challenge was actually making a good looking wrist band for the watch. I originally intended to use a design like this but it turned out that due to lack of enough para cord I had left, I went with a simpler design that I had done once before.

The watch in it's natural environment. The time displayed is 18:23 (6:23 PM)
The watch in it’s natural environment. The time displayed is 18:23 (6:23 PM)

Continue reading