analyzing SPI on an MCP3208 12-bit analog to digital converter

The MCP3208 12-bit analog-to-digitial converter is the basis of my battery load test analyzer and online monitoring system which I call pid3A .  As I have mentioned before,  I implemented a bit-banged SPI driver for the mcp3208 in the perl programming language.  I use the analog-to-digital converters (adc’s) to sample the voltages of each cell in the battery plant at regular intervals to make graphs of the discharge curves.

MCP3208 Analog to digital converter
MCP3208 Analog to digital converter

pid3A is in it’s 2nd prototype and can accurately measure up to 24 cell voltages at a time with it’s three 8-channel mcp3208’s.  Occasionally, I will burn up a single channel on one of the adc’s, rendering the whole chip useless for my application.

I have written a lot of diagnostic software for pid3A to make sure the adc’s are functioning properly before I begin an IEEE450  load test.  To test all 24 channels, I made a test plug that puts 2.5VDC on each channel, takes 5 samples, and give the the binary output code and actual voltage of each sample.  It then gives me a color-coded go/no-go visual indication.  If there are any bad channels, I just change out the adc chip and re-run the diagnostic test.

mcp3208 test plug
pid3A test plug

Here is a sample of the output:

mcp3208 diagnostics
diagnostic testing of each ADC channel

You can see that the adc output codes and voltages are very steady.  The voltage is a function of the digital output code of the adc.  Above, most of the output codes are 2049.  Knowing this, and the reference voltage of 4.998VDC, you can calculate the actual voltage using this equation:

mcp3208 digital output code equation
mcp3208 digital output code equation

This is absolutely necessary for troubleshooting quickly, but sometimes I need to know what is going on at a microscopic level.  My multi-channel logic analyzer is the perfect tool to look at the underlying SPI protocol.

IEEE450 battery load test analyzer
IEEE450 battery load test analyzer

I know this just looks like a mess of wires, but I have my logic analyzer hooked up to the data-in, data-out, chip select, and clock lines of one of my mcp3208 chips.  Here is a close up of a frame from my diagnostic script:

SPI examination using PulseView
SPI examination using PulseView

This shows the driver clocking in 19 pulses.  The first few bits on the MOSI line tell the adc to use single (as opposed to differential) mode, and sample channel 001.  The rest of the MOSI bits are ‘don’t care’ bits, so my driver just set them all high.  The MISO line is the mcp3208 clocking out the actual binary output code.  In this case it is 2045, which in binary is 011111111101.  The slave select line goes low to initiate a sample, and goes high when finished.  PulseView shows me precisely what is happening, and lets me easily analyze the SPI protocol for proper function per the datasheet below:

mcp3208 SPI protocol framing
mcp3208 SPI protocol framing

HiLetgo 24MHz 8-channel logic analyzer + PulseView

I just recently got a HiLetgo 24MHz 8 channel USB logic analyzer on Amazon for $11.  I am blown away what you can do with it.

HiLetgo 24MHz 8-channel logic analyzer
HiLetgo 24MHz 8-channel logic analyzer

I downloaded a copy of the AppImage forPulseView at  With this setup, I have an amazing multi-channel oscilloscope right on my computer for just a few dollars.

I have three examples to show some of it’s capability based on some of my recent posts

  1. an example of a bit-banged SPI driver I wrote for a MAX7219 7-segment display driver
  2. the output of the 555 timer circuit I built in a recent post
  3. the I2C sda and scl lines of the MCP23008 perl-based gpio extender driver I wrote.

Here is the setup I have for the MAX7219 display driver.

pine64 driving a MAX7219 display driver

I am using my new pine64 to drive the display.  The datasheet for the max7219 describes in detail how to operate the chip like how to configure the driver via control registers and the data format. Below is the expected data format per the datasheet:

MAX7219 data format
MAX7219 data format

I connected my logic analyzer to the MOSI, CLK, and slave select lines and here is the output in PulseView.

Pulseview SPI
Pulseview SPI scan

You can see on the slave select line, I go high and low and then bang in 16 pulses on the clock line.   The data is on the MOSI (master out, slave in) line and tells the driver which LED’s to turn on.  This is awesome for troubleshooting problems with digital circuits.  What is really cool is PulseView’s ability to decode SPI.  The bottom line show the content of the frames in hex and binary.

Pulseview decoding SPI frames
Pulseview decoding SPI frames

One thing I find interesting with my perl based, bit-bang driver is that the clock pulses are irregular in their duty cycle.  This is easy to see if you zoom in on the clock line.

SPI Clock line of bit-banged driver. Irregular duty cycle.
SPI Clock line of bit-banged driver. Irregular duty cycle.

Each dot on the square wave represents a sample pulseview took.

Now for the output of the 555 astable multi-vibrator circuit I recently blogged about.  These were the parameters of my circuit.

555 timer calculator output
555 timer calculator output

And here is what PulseView saw.

555 astable multivibrator output seen with pulseview
555 astable multivibrator output seen with pulseview

The calculator says 4.3Hz and a 52.38% duty cycle.  That is pretty much what PulseView said.  The output of the 555 timer is very precise and regular.

Finally, lets take a look at an I2C example using my MCP23008 driver from the binary counter example I recently blogged about.  Well, this is the first scan with the logic analyzer that I am actually using the device’s hardware, in this case I2C.  That being the case, it is much faster than my bit-bang SPI example, and certainly the 4.3Hz 555 circuit.  At first glance, it doesn’t look like much.  I did tell PulseView what protocol I was using, and which lines were sda and scl.

I2C Logic analyzer output
I2C Logic analyzer output

You just see some periodic blips on the lines, but the frames are accurately decoded.  You have to zoom in to see what precisely is going on with the pulses.

I2C clock pulses
I2C clock pulses

Above is a blown up view of one of the blips from the complete trace above.

Every maker should have a logic analyzer for development and troubleshooting, and I highly recommend the HiLetgo analyzer I use.

decoding ADS-B with rtl-sdr

Per Wikipedia:

Automatic dependent surveillance—broadcast (ADS–B) is a surveillance technology in which an aircraft determines its position via satellite navigation and periodically broadcasts it, enabling it to be tracked.

It’s really easy and fun to see what planes are flying near you with a software-defined-radio dongle and dump1090.

After installing dump1090, you can see nearby aircraft information like the flight number, altitude, lat/lon, and speed.  Here’s what I saw one afternoon near Memphis, TN:

./dump1090 --net --interactive

dump1090 command line mode
dump1090 command line mode

After just a few seconds on starting dump1090, planes start to appear.  To view this information on a map, launch a browser and go to localhost port 8080.


dump1090 web interactive
dump1090 web interactive
dump1090 flight information
dump1090 flight information

It even provides links to FlightAware, so you can see even more information about a particular flight.

Flight Aware
Flight Aware
Flight Aware website
Flight Aware website perl + CGI

KJV Bible
KJV Bible

I have been a Christian since I was 12.  I began reading the Bible for myself at 13.  I became more serious in my study at 20, and have been diligently studying ever since.  I enjoy it tremendously.  I really try to meditate on what I am studying; try to imagine what it must have been like for the people involved;  try to understand why a certain passage is in the Bible and it’s true meaning; is there something in between the lines I can deduct?   Along those lines, I like to hear what other people think about it.  Those with whose theology I agree with, and those I do not.  Those who reject it all together, and why they think that way.

I also read several Bible commentaries as I study.  There are so many of them out there.  Most of which, I have no interest in.  There is also so much software and Bible study websites out there that it can be bewildering.  I decided that I wanted to make my own Bible study website that suits me, and only contains the resources that I am interested in.

When I decided undertake this project several years ago, I had a successful free-lance website business called Nerd for Hire.  I was building and hosting custom designed PHP web applications, primarily serving real estate industry and used car lots in the greater Memphis, TN area.  I was  focused on PHP/MySQL, the then new jQuery, AJAX, CSS, etc., and hosting it all on a reseller account I had with Host Gator.  It was a nice side gig until Craigslist started charging $5 for dealers to post cars on their site.  Craigslist was essential for directing traffic to the dealer’s website where the whole inventory could be advertised.  I briefly moved over to, but it just wasn’t the same.  Increasingly, my customers wanted incredible, custom-made web applications (my specialty), but didn’t want to pay much for them.  It became to much effort for too little financial reward, and I ended up folding.


This was around 2010.  Perl was unfashionable at this time, and perl/CGI was certainly not the tool of choice for web applications anymore as fast as PHP had gotten.  Never one to go along with fads,  I had been reading an entry-level perl book that was 8 years old at the time (got it for $0.01 + $3.99 shipping on Amazon),  and I was VERY interested in learning perl because it seemed like it could do everything: text processing, databases, windows applications, server side scripting,  etc.

perl books

I figure the best way to learn a new language is to do a big project in it.  I proceeded to write a CGI application in perl to read the King James Version Bible.  Am I KJV only? No.  Is it my favorite? Pretty much.  I forget where I found a SQL file of the KJV bible, but I did, and imported it into my home LAMP server via phpmyadmin.  I then wrote an object oriented CGI application to read the Bible on my home network.   I purposefully ignored any css styling, and just wanted a simple, stripped down design.  I began using it daily during my study, being really pleased with myself for having got that far.

I was using Power Bible CD at the time, and had really taken a liking to the Adam Clarke Bible Commentary.  I wanted to add it to my little project so I didn’t have to go between applications during my study.  I created a database schema and manually copied and pasted every single chapter of the Adam Clarke Commentary from  It was tedious, and painful, but it worked.  Once I had it in database form,  I added scripting so that the commentary was displayed side by side with the chapter in the Bible I was reading.  Soon after, I added the Joseph Benson Commentary in the same inefficient fashion.

After some time, I discovered the Internet Sacred Text Archive,, which contained numerous Bible commentaries and other interesting resources.  I got a little more sophisticated, and wrote scripts (wget + perl) to automatically download the commentaries chapter by chapter and save them as text files on my computer.  I then wrote scripts that  merged them all together into a csv file, and imported them into a MySQL database.  I did the same with a few Bible dictionaries, encyclopedias, etc. from the Internet Archive.  I was getting pretty good with perl’s regular expressions and amazed at how easy it was to do really powerful things in perl with such little effort.

So, I got my CGI application together the way I wanted it, and was still just using it on my internal LAMP server.  I had recently started renting a VPS from for a for-sale-by-owner real estate project.  I decided to put my humble project on the internet, since I already had the hosting resources.  I decided to go with a free domain:  I am still hosing it on a VPS from digitalocean.  Other sites I am hosting there are using PHP 7.  PHP is smoking fast, and comes with OPcache standard.  On the other hand, perl CGI is an anachronism, SUPER DUPER slow, and taxing on the CPU.  I really don’t care though.  It’s out there for the world to see.  Ad-free and just a simple, easy-to-use place to study the Bible.

Hebrew New Testament
Hebrew New Testament at

Building an astable multivibrator circuit with a 555 timer

I haven’t built any sequential logic circuits since electronics school.  Back then,  a 555 timer was used as a clock source to drive JK flip-flops connected to the address lines of EEPROMS that contained programs I had written in hexadecimal.  In a world of super cheap Arduinos, raspberry pi’s, etc.  the days of making projects in that manner are long gone, for me anyway.   That was really fun stuff though, and I have a bunch of 555 timers in my parts bin.  So, I decided to tinker, and see if maybe I got some inspiration.

I built the astable multi-vibrator circuit straight out of the datasheet.

555 astable multi-vibrator
555 astable multi-vibrator
  • r1:  100K ohm
  • r2: 1M ohm
  • c1: 160nF

According the this awesome calculator, I’m running at about 4.3Hz with about a 50% duty cycle, which looks about right.

555 timer calculator output
555 timer calculator output
5 astable multivibrator circuit
555 astable multivibrator circuit

using the MCP23008 gpio expander with chip Pro and perl

I’ve mentioned the next thing co.  chip family of single board computers before.  It was billed as the world’s first $9 computer.  I first heard of it on NPR one morning and couldn’t get to a computer to pre-order one fast enough.  A full-blown debian distribution, wifi, i2c, SPI, 8-gpio pins, composite video, UART, USB and more about the size of a credit card.  It seemed too good to be true.  I guess it was, because they did not last long.  I bought 15 of them, but never received the last five before they tanked.  They also came out with the chip Pro,  an even smaller, somewhat stripped down version of the chip aimed at being a platform for mass-produced products for $16.  I really liked the optional ufl wifi antenna port.  With an external high-gain antenna, it is really great at sniffing wifi networks.   It is totally awesome, and I wish I had 100 of them.

chip pro
chip Pro

Sadly, I burned up all my gpio pins on a project.  I didn’t want to scrap my chip pro, however, and decided to use the MCP23008 gpio I/O expander to get my gpio back up and working.

I wrote my own easy to use perl based driver to interface with the MCP23008.  There are some great tools on CPAN that implement I2C for stuff like this, but I went an even simpler route.  My driver (at a mere 40 lines of code)  uses system calls (via backticks)  to read and write to registers on the gpio expander.  For example, to read the gpio register, the script will just make a system call like so:

sudo i2cget -y 1 0X20 0x09

This tells the chip Pro to talk to the i2c device on bus 1, at address 0x20, and read the value in register 0x09 (gpio register).   Here is the driver in it’s entirety:

#!/usr/bin/perl -w
use strict;

utilities for MCP23008 gpio extender
execute any scripts that use this as sudo

#global variables
my $address;
my $gpio_w = 0;

sub gpio_enable{
	#function takes the i2c address of the MCP23008
	#it also  sets the IO direction
	#register.  Must be a value from 0-255
	#1 is input, 0 is output

	$address = $_[0];
	my $ioreg_val = $_[1];

	#write io reg
	`i2cset -y 1 $address 0x00 $ioreg_val`;
}#end gpio_enable

sub gpio_read{
	#function uses i2cget to
	#read gpio register 0x09
	my $reading = `i2cget -y 1 $address 0x09`;
	return $reading;
}#end gpio_read

sub gpio_write{
	#takes int from 0-255 to write to the
	#gpio register
	$gpio_w = $_[0];
	`i2cset -y 1 $address 0x09 $gpio_w`;
}#end gpio_write


So simple, I’m embarrassed, but it works great.  To test, I wrote a simple script that visually counts to 255 in binary with LED output.

perl mcp23008 driver
i2c mcp23008 binary counter with chip Pro and perl

Here is the script:

use strict;
use Time::HiRes qw(usleep);
require '';

#init the 23008 IO register as output
gpio_enable(0x20, 0);

for(my $i=0;$i<256;$i++){
}#end for



getting started with snort

 snort IPS
snort IPS

Wireshark is great.  Personally, I prefer tcpdump from the command line with my own scripts to extract specific results I am looking for.  If you want to become dangerous with tcpdump, you should check out Daniel Miessler’s tutorial on the subject and start experimenting.  That being said, my ideas of how to see what is actually going on in networks that I manage are constrained to my limited knowledge base, experience and imagination, and I am sure it is not terribly hard to outsmart me:

  • is my LAMP server getting hit with  SQL injection attacks?
  • is there some (unknown to me) vulnerability to a package on my system that I am not aware of yet?
  • is a device on my network compromised by some type of malware?
  • is the NSA all up in my biz?
  • am I getting port-scanned?  If so, by whom? What are they looking for?
  • is someone trying really hard with nmap scripts or other penetration tools to hack me?
  • some kinds of attacks I can’t even fathom?

I’m pretty sure at this point, the answer to all of these questions is YES!  Well, I want to know what the heck is going on, and even with decent tcpdump skills, I am not sure how to tell if, for instance, I am being hit with an OS detection scan or something like that.  Snort is the perfect tool for problems like this.

Snort sniffer mode

Snort’s sniffer mode is pretty cool.

sudo snort -i enp1s0 -dev

This command will basically show every frame on the wire whether IPv4, IPv6, et. al,  with the hex and ascii output to the console.  Here is the output from this command:

snort sniffer mode
snort sniffer mode

If I just want to see frames moving on my LAN in this manner, snort is definitely not my tool of choice; tcpdump is.  However, in sniffer mode, I can capture and log network traffic in binary  (which is incredibly fast) and analyze it later.  But, I want to be alerted about intrusions…..

Snort Network Intrusion Detection Mode

This is what I think makes snort special.  I installed snort as an NIDS on a few machines in my lab by following this awesome turorial. I intend to attack my snort machines and post the results soon.

battery discharge analyzer

pid3A Battery loadtest analyzer
pid3A Battery loadtest analyzer

This is the first of probably several posts about a battery discharge analyzer I have been perfecting for a little over a year now. I work in the telecommunications field where uninterrupted power is a must. To achieve this, there are large, high-capacity backup battery plants that keep equipment up and running in the event of a commercial power outage. Generally, but not always, these are -48 volt DC lead-acid batteries  anywhere from 50 amp-hour to over 2000 amp-hour depending on the application and power requirements of the facility they are backing up. It is important to know how long a battery plant will be able to supply power before a facility goes down. To calculate this, you take into factor the combined current draw of all the equipment, and the amp-hour rating of the batteries. So, if your equipment loads the batteries at 15 amps, and you have 200-AH batteries, you should be able to power the site for 13.3 hours if your batteries are at 100% capacity.

hours of backup power = amp hours / site load

200AH / 15A site load = 13.3 hours (assuming 100% battery capacity)

But what if the batteries are not at 100% capacity?  What if they are in poor condition and have much less than 100% capacity?  How do you know?  The answer is capacity testing with a load bank.  IEEE450 describes load testing recommendations for vented lead-acid battery plants and IEEE1188 for valve-regulated lead-acid (VRLA) battery systems.  While this load test analyzer will work with any type of battery composition,  I have focused on lead-acid batteries.

characteristic discharge curve of a lead-acid cell
characteristic discharge curve of a lead-acid cell

The picture above shows a characteristic discharge curve of a lead-acid cell under a slight load.  It dips into a trough,  rebounds, and discharges somewhat logarithmically until it totally drops off.  This graph was generated by my load test analyzer, which I refer to as pid3A (pi, as in raspberry pi, data acquisition and analysis).  It takes thousands of samples,   plots the results on dynamically generated graphs, creates user-defined reports,  stores results for download, and displays test results via it’s internal web server.

Right now, I am on my second prototype.  It can sample up to 24 individual cells during a load test.  It can function as a stand-alone analyzer that travels with a separate load bank, or an online all the time battery monitoring system.

IEEE450 IEEE1188 load tester invention
pid3a battery load test analyzer in online monitoring system configuration

The samples are taken by three MCP3208 12-bit analog to digital converters (ADC).  Each chip has eight inputs, and is connected to a dedicated voltage reference.  I wrote a bit-banged driver for the ADC chip in perl using my own gpio interface.

MCP3208 Analog to digital converter
MCP3208 Analog to digital converter
MCP3208 Connections to raspberry pi
MCP3208 Connections to raspberry pi

The maximum input voltage the ADC’s can sample is 5VDC, so I had to make an adjustable voltage divider network to tune each cell input into the device.

Voltage divider network
Voltage divider network

The sampling rate is user defined.  During the discharge test, results are written to a CSV file which is used later to process the results, and generate the graphs and reports.

To keep the file small, it contains the unix epoch timestamp, sample number, the cell# being sampled,  the binary OP code from the ADC reading, and the voltage relative the negative terminal of the battery plant (calculated from the ADC opcode and some test parameters).

I used the DBD::CSV database driver from cpan to mine data and produce results from the readings contained in the csv file.  I also developed a handy desktop application for testing  that can generate graphs for my device, or any other general purpose csv database.

CSV database analyzer
CSV database analyzer

Below is a graph produced by pid3A of a 350Ah 24-cell VRLA load test that failed about half way through.  You can clearly see that a few cells began failing quickly, and nearly reversed polarity.

VLRA load test results
VLRA load test results

Like I said, this is merely an introduction to the pid3A loadtest analyzer with more to follow.

Here is an incomplete whitepaper I did for the first prototype some time ago.  It shows how far pid3A has come