Close

Software

A project log for Affordable Spectrum Analzyer

Analyze electrical signals using a raspberry pi with a user interface designed for students, hobbyists, and other beginners.

dan-kislingDan Kisling 07/10/2016 at 22:170 Comments

In this log we'll focus on all of the software. Most of the logs so far cover stuff that could be developed or done in a week or two. This log is very different. The one piece of software (the device driver) alone took most of the academic year to develop. All of the software was developed by my lab partner and local genius, Andrew. That is, with the exception of the GUI: I wrote that.

The software developed for this project is divided up into three parts. The software is broken into three separate systems, the driver, the controller and the user interface. Each sub-system is responsible for a different task and is separated by operational priority. The driver, interacting directly with the Raspberry Pi hardware, has the highest priority, requiring accurate timing and as-fast-as-possible computing time for consistent sampling. The controller has the next highest priority for processing time as it responsible for computing the fast fourier transform and reconstructing the segmented spectrum. At the lowest priority and least mathematical computations is the user interface, responsible for plotting the spectrum and interacting with the user.

Device Driver

Github link to code for driver, and header file.

The purpose of the device driver is to provide an interface between the hardware and the higher level software. The driver is responsible for physically writing out SPI commands to the local oscillator, physically changing the pin levels for the amplifier, setting up and altering the sampling clock, and reading in the input bits from the ADC. In order to accomplish this level of control, the driver is written as a linux kernel module for both a character device and SPI device.

The character device aspect allows the board to be interacted with like a normal file in software would. Namely, the driver allows the device file to be opened, read, written to, memory mapped and closed in order to interact with the physical bored. Opening the device opens a channel for interacting with the driver, similar to opening a text file to edit it. Reading the device prompts the driver to take samples for a predetermined number of samples and step the local oscillator a predetermined number of steps, storing all results in a 1 MB buffer in kernel space. Kernel space is a separate region in memory, distinct in the linux operating system, which is reserved for low-level hardware and driver interaction. In order to use this data, memory must either be copied into user space, where user applications run, or it must be mapped there, Since the user interface runs in user space, the driver allows for portions of the data buffer to mapped using memory mapping. Writing to the file allows for the driver’s internal values to be modified, For example, the local oscillator steps, sampling frequency and amplification level can all be changed by writing to the driver. To facilitate this, all data must be formatted correctly, so the driver can interpret the changes correctly. Finally, closing functionality closes the channel safely, similar to saving and exiting a text file.

The functionality not exposed by the character device are the initialization and cleanup of the device. During initialization, all memory buffers are created, the GPIO pins are formatted to their expected operation and the sampling clock is set to the correct frequency. This guarantees that if the system were to change from other software on board, when the device starts each time, device is in a known and guaranteed state. The cleanup functionality reverses the effects of the initialization so the board returns to a state that is not utilizing resources unnecessarily.

In addition, the SPI interactions are logged as a separate device and driver, following the SPI driver interface. The device itself does not expose any SPI interactions with the user, but utilizes them during sampling, thus it is necessary to register a secondary driver. This driver purely handles unidirectional communication from the Raspberry Pi to the local oscillator on the board to change its value.

Using the driver and device requires that the driver is loaded as a standalone kernel module and that a device file be made in the /dev/ directory. After that, the device file made in /dev/ can be interacted with like a normal file for any of the above listed file interactions.

Controller

Github link to code.

The controller, as its name suggests, is responsible for interfacing all other user space applications to the kernel space driver. This program reformats edits to the driver from the user interface into the expected byte-code by the driver for writing to the device. Similarly, it formats the byte-code data from the sampled signal into useable, floating point data values. These data values, after formatting, are used to compute the fast fourier transform and generate segments of the spectrum. Finally, the controller is responsible for piecing together the spectra segments into one final spectrum and output it to a user space file for the interface.

The controller, at the moment, uses terminal commands to operate. After running the application, it parses additional flags for values to test in the driver. The interface (Or even the terminal) can send additional flag commands to operate the driver for testing or for full fledged operation. Though, functionally this provides all necessary operations, it does include additional latency, so it is not an optimal final solution. A better final solution would be to wrap the C- code in python, so the user interface can call the functions directly, bypassing latency in calling shell commands.

GUI

Github link to code.

The GUI’s main goal is to display the spectrum and allow the user to change settings for the device in an intuitive manner. The code is based off of a bitcoin tracking program developed by Harrison Kinsley on PythonProgramming.net (with a creative commons liscense that is free to use). The program uses TKinter and Matplotlib to create a graphical interface using simple code in python. Below is the simplified system block diagram of the general principles of operation of the GUI.

System Block Diagram for GUI Operation

One of the applications features is its default settings. By just starting the application, you can immediately start collecting data, without having to give the program any parameters. To enhance the data collected you can change the settings via the application. The program has the following options available from the top menu:

Screenshot of GUI with fundamental frequency detection on

Possibly the most useful functionality of application comes from built in functionality in the matpotlib library.

Matplotlib navigational menu. From left to right:

Reset to Original View, Back to Previous View, Forward to Next View, Pan axes with

left mouse, zoom with right, Zoom to rectangle, Configure Subplots, Save the Figure

This allows the user to zoom into any part of the graph they like and also save that graph as an image (which is one of the goals of this project).

Discussions